Feature #747

/\A/u ignores BOM

Added by Shyouhei Urabe over 6 years ago. Updated almost 4 years ago.

[ruby-dev:37075]
Status:Rejected
Priority:Normal
Assignee:Yui NARUSE

Description

=begin
/\A/uがBOMにヒットしないのが嬉しくないです。普通、BOMはあるとすれば文字列の先頭に付いていることが多いので、/\A/uがBOMにヒットするのが自然だと思います。

あるいは/\Z/と/\z/のようにBOMにヒットする/\a/としない/\A/とかあってもいいかもしれませんが、いずれにせよBOMを適切に先頭とみなしてくれるメタキャラクタを希望します。でないと毎回 /\A(\xEF\xBB\xBF)?/uとか書かないといけなくなって非常に面倒です。

% ~/target/branches/ruby_1_9_1/bin/ruby -Ku -ve 'p /\Afoo/u =~ "\xEF\xBB\xBFfoo"'
ruby 1.9.1 (2008-11-12 revision 20221) [x86_64-linux]
-e:1: warning: ambiguous first argument; put parentheses or even spaces
nil
=end


Related issues

Related to Ruby trunk - Feature #802: IO.open optional argument to properly handle BOMs Closed 11/30/2008
Related to Ruby trunk - Feature #1951: openのBOM指定拡張 Closed 08/18/2009

History

#1 Updated by Toru Iwase over 6 years ago

=begin

On Wed, 12 Nov 2008 17:49:47 +0900
In article
[ [Feature #747] /\A/u ignores BOM]
Shyouhei Urabe redmine@ruby-lang.org wrote:

/\A/uがBOMにヒットしないのが嬉しくないです。普通、BOMはあるとすれば文字列の先頭に付いていることが多いので、/\A/uがBOMにヒットするのが自然だと思います。

http://www.ietf.org/rfc/rfc3629.txt
RFC 3629 を読むと、内部処理には U+FEFF を特別扱いしないことを推奨してい
るように思いますが、どうなんでしょう。

--
Tietew tietew@tietew.net
Blog: http://www.tietew.jp/
PGP: 26CB 71BB B595 09C4 0153 81C4 773C 963A D51B 8CAA

=end

#2 Updated by Shyouhei Urabe over 6 years ago

=begin
卜部です。

Tietew さんは書きました:

On Wed, 12 Nov 2008 17:49:47 +0900
In article
[ [Feature #747] /\A/u ignores BOM]
Shyouhei Urabe redmine@ruby-lang.org wrote:

/\A/uがBOMにヒットしないのが嬉しくないです。普通、BOMはあるとすれば文字列の先頭に付いていることが多いので、/\A/uがBOMにヒットするのが自然だと思います。

http://www.ietf.org/rfc/rfc3629.txt
RFC 3629 を読むと、内部処理には U+FEFF を特別扱いしないことを推奨してい
るように思いますが、どうなんでしょう。

同じRFCに、

It is therefore RECOMMENDED to avoid stripping an initial U+FEFF
interpreted as a signature without a good reason, to ignore it instead
of stripping it when appropriate (such as for display) and to strip it
only when really necessary.

とあります。専門家ではないので外してるかもしれませんが、この(such as for
display)のところに正規表現マッチも含まれるんじゃないでしょうか。

=end

#3 Updated by Usaku NAKAMURA over 6 years ago

=begin
こんにちは、なかむら(う)です。

In message " Re: [Feature #747] /\A/u ignores BOM"
on Nov.12,2008 18:40:30, tietew@tietew.net wrote:

/\A/uがBOMにヒットしないのが嬉しくないです。普通、BOMはあるとすれば文字列の先頭に付いていることが多いので、/\A/uがBOMにヒットするのが自然だと思います。

http://www.ietf.org/rfc/rfc3629.txt
RFC 3629 を読むと、内部処理には U+FEFF を特別扱いしないことを推奨してい
るように思いますが、どうなんでしょう。

というわけで、以前の議論で結論が出ずに見送りになりましたが、
やはりBOMを理解するopenが必要なんじゃないでしょうか。

なお以前の議論の際の結論自体はにまとめてあり
ますが、あの時は書き込み時にBOMをどう扱えばいいのか判断できな
かったのが見送りの主原因でした。
今回は、書き込みは現状どおりとして、読み込み時のみBOMを取り扱
うという案を提案してみます。
# なお1.9.1に入れることは想定していません。

  • 対象となるのは"r"のみ。"r+"、"w+"、"a+"は対応しない。

  • "r"時のエンコーディング名指定として、"utf-7-bom"、"utf-8-bom"、
    "utf-16le-bom"、"utf-16be-bom"、"utf-32le-bom"、"utf-32be-bom"
    をサポートする。
    これらが指定されたとき、BOMがあるかどうか判断できるまでファ
    イル先頭を読み、BOMがあればそのBOMに従ったエンコーディング
    が指定されたとみなして、読んだBOMは捨てる。
    BOMがなければ既に読んだ分をungetbyteした上で"-bom"なしのエ
    ンコーディングが指定されたとみなす。

  • 他は現状を変更しない。つまり例えば"w:utf-8-bom"などの指定は
    Unsupported encodingとして無視される。

※UTF-7にBOMがあるのかどうかよくわからないんですが、絶対にな
いんだったら上記からutf-7-bomは取り除きます。

それでは。
--
U.Nakamura usa@garbagecollect.jp

=end

#4 Updated by Martin Dürst over 6 years ago

=begin
At 18:40 08/11/12, Tietew wrote:

On Wed, 12 Nov 2008 17:49:47 +0900
In article
[ [Feature #747] /\A/u ignores BOM]
Shyouhei Urabe redmine@ruby-lang.org wrote:

/\A/uがBOMにヒットしないのが嬉しくないです。普通、BOMはあるとすれば文字列の
先頭に付いていることが多いので、/\A/uがBOMにヒットするのが自然だと思います。

http://www.ietf.org/rfc/rfc3629.txt
RFC 3629 を読むと、内部処理には U+FEFF を特別扱いしないことを推奨してい
るように思いますが、どうなんでしょう。

U+FEFF は BOM の役割だけではなく、ZERO WIDTH NON BREAKING SPACE と言う役割
もありますし、正規表現では多くの場合ファイルの先頭ではなく、単なる何かの
文字列をマッチしますので、BOM を特別扱い刷るのは好ましくないと思います。

どうしても今より Ruby の BOM への対応を強化したいとなら、文字列変換
(ファイル入出力限定) で :bom => :remove (入力の場合) とか :bom => :add
(出力の場合) とかの方向で考えた方がいいかと思います。

宜しくお願いします。 Martin.

#-#-# Martin J. Du"rst, Assoc. Professor, Aoyama Gakuin University
#-#-# http://www.sw.it.aoyama.ac.jp mailto:duerst@it.aoyama.ac.jp

=end

#5 Updated by Martin Dürst over 6 years ago

=begin
At 19:31 08/11/12, Urabe Shyouhei wrote:

卜部です。

Tietew さんは書きました:

On Wed, 12 Nov 2008 17:49:47 +0900
In article
[ [Feature #747] /\A/u ignores BOM]
Shyouhei Urabe redmine@ruby-lang.org wrote:

/\A/uがBOMにヒットしないのが嬉しくないです。普通、BOMはあるとすれば文字列
の先頭に付いていることが多いので、/\A/uがBOMにヒットするのが自然だと思います。

http://www.ietf.org/rfc/rfc3629.txt
RFC 3629 を読むと、内部処理には U+FEFF を特別扱いしないことを推奨してい
るように思いますが、どうなんでしょう。

同じRFCに、

It is therefore RECOMMENDED to avoid stripping an initial U+FEFF
interpreted as a signature without a good reason, to ignore it instead
of stripping it when appropriate (such as for display) and to strip it
only when really necessary.

これはファイル全体の場合には、例えば電子署名などの関係でよく分かりますが、
スクリプトなどでファイルをこま切れして処理するときにはなかなか難しいです。
基本的には読み込みの時に BOM を除去し、必要でしたらその有無を記憶し、
出力に必要に応じて未だ付けるのが正しいと思います。そうしないと処理によって
BOM が先頭からファイルの内部に移動するなど意味のない結果になってしまいます。

極端に言うと /\A\uFEFF/u はどういう場合にマッチすべきでしょうか。

宜しくお願いします。 Martin.

とあります。専門家ではないので外してるかもしれませんが、この(such as for
display)のところに正規表現マッチも含まれるんじゃないでしょうか。

#-#-# Martin J. Du"rst, Assoc. Professor, Aoyama Gakuin University
#-#-# http://www.sw.it.aoyama.ac.jp mailto:duerst@it.aoyama.ac.jp

=end

#6 Updated by Usaku NAKAMURA over 6 years ago

=begin
こんにちは、なかむら(う)です。

In message " Re: [Feature #747] /\A/u ignores BOM"
on Nov.13,2008 17:32:25, konishih@fd6.so-net.ne.jp wrote:

の方も読んでみて、今の状況がよくわからなかったので質問さ
せてください。現時点でRuby-1.9系は2BYTE Unicodeの文字列を読み込んだ場
合、どのような内部表現となるのでしょうか。

すみません、2BYTE Unicodeってなんでしょう?

A:
仮にUCS-2を(リトルエンディアンなりビッグエンディアンなりで)そ
のまま吐き出したもの、のことだとすると、そのようなエンコーデ
ィングはRubyではサポートされないので、単なるバイナリ列として
扱うしかありません。
そういう意味では「2.」です。

B:
とはいえ、おそらくそのようなデータはUTF-16LEなりUTF-16BEなり
として解釈可能でしょうから、ユーザがそのように指定すればその
ように解釈されて読み込まれます。
その際、読み込まれた文字列の内部形式はやっぱりユーザ指定によ
るのでどうなるかはスクリプト依存ですが、無変換で読み込まれた
ならば、内部形式自体はそのままです。
ただし、1.9のStringは自分のエンコーディングを知っていますから、
上記Aの場合と異なり、「単なるバイナリ列」ではありません。

3は、全く想像がつきませんが、1の立場をとるのであればBOMは内部表現として
不要ですし、逆に2.の立場であれば、必要ですのでBOMが内部表現に入っていな
いのは不自然に映ります。

というわけで、元のデータの意味とその読ませ方によります。
Aの場合はBOM(に限らず全てのデータ)を特別扱いする理由は存在し
ません。
Bの場合はエンコーディングは判明しているのでBOMは不要ですね(あ
ってはいけないという意味ではない)。

それでは。
--
U.Nakamura usa@garbagecollect.jp

=end

#7 Updated by Usaku NAKAMURA over 6 years ago

=begin
こんにちは、なかむら(う)です。

In message " Re: [Feature #747] /\A/u ignores BOM"
on Nov.13,2008 18:13:39, konishih@fd6.so-net.ne.jp wrote:

大体分かってきたような気がします。普通にopenで読み込んだ場合は2.(=A)なの
ですね。でStringオブジェクトに変換した場合は、エンコーディングを持つ(B)
と。

あー、普通、というか、エンコーディングを指定せずにファイルを
オープンした場合はlocaleのエンコーディングを指定したとみなさ
れます。
ので、2.(=A)にはならないで、おそらく間違ったエンコーディング
が付与された文字列が生成されてしまうと思われます。

なので、正常系としては、明示的にエンコーディングとしてバイナ
リ列(ASCII-8BIT)が指定されるか、明示的にUTF-16LEまたはUTF-16BE
が指定されるか、いずれかしかありえません。

やはり、正規表現を使うのであれば、Bの状態でBOMを付けない方が良いと思いま
す。あえてAの状態で先頭マッチを行う場合でも、「文字列」という本義を考え
るとBOMまでマッチさせるのには違和感を感じます。

そういえば、/\A/に対する私の意見を述べていませんでした。

バイナリ列に対する正規表現マッチにおいては、BOMというものはな
い(zero width non breaking spaceという文字もない)ので、BOMで
あったはずのデータ("\xfe\xff"または"\xff\xfe")が/\A/にマッチ
することはありえないと私も思います。

Bの場合、BOMがBOMであると判明しているならばそれが/\A/にマッチ
してもおかしいとは思わないのですが、既に読み込まれた文字列に
おいて冒頭の"\ufeff"がBOMだったのか単にzero width non breaking
spaceだったのかを区別することは不可能でしょうから、/\A/でマッ
チさせるのにはやはり無理があるのではないかと思います。
# /\A/の意味は変えずに「先頭および先頭の"\ufeff"にマッチする
# 特殊文字」を別途導入するのはありえないこともないと思います。

が、まあ、やはり先に提案したとおり、最初にBOMが自動的に読み捨
てられるopenを用意するのが無難だろうと思います。

それでは。
--
U.Nakamura usa@garbagecollect.jp

=end

#8 Updated by Yukihiro Matsumoto over 6 years ago

  • Status changed from Open to Rejected

=begin
BOM対応が不要とは言いませんが、正規表現で対応するのはよくないと思います。
=end

#9 Updated by Shyouhei Urabe over 6 years ago

=begin
なお、べつに正規表現で対応されていなくても、私が直面している問題(つまり/\A#{foo}/に
File#readした文字列を渡しても意図したマッチにならない)が解決されれば構いません。

つまり正規表現で対応しないならopen側で対応して欲しいわけですが、それは新たにチケット
起こした方がいいんですかね?
=end

#10 Updated by Yukihiro Matsumoto over 6 years ago

=begin
まつもと ゆきひろです

In message "Re: [Feature #747] /\A/u ignores BOM"
on Fri, 28 Nov 2008 19:18:13 +0900, Shyouhei Urabe redmine@ruby-lang.org writes:

|なお、べつに正規表現で対応されていなくても、私が直面している問題(つまり/\A#{foo}/に
|File#readした文字列を渡しても意図したマッチにならない)が解決されれば構いません。
|
|つまり正規表現で対応しないならopen側で対応して欲しいわけですが、それは新たにチケット
|起こした方がいいんですかね?

はい。お願いします。

=end

Also available in: Atom PDF