8

鬼車のドキュメントによると、\d文字タイプは次のように一致します。

decimal digit char
Unicode: General_Category -- Decimal_Number

ただし、\dすべての Decimal_Number 文字を含む文字列をスキャンすると、ラテン語の 0 ~ 9 桁のみが一致します。

#encoding: utf-8
require 'open-uri'
html = open("http://www.fileformat.info/info/unicode/category/Nd/list.htm").read
digits = html.scan(/U\+([\da-f]{4})/i).flatten.map{ |s| s.to_i(16) }.pack('U*')

puts digits.encoding, digits
#=> UTF-8
#=> 0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९০১২৩৪৫৬৭৮৯੦੧੨…

p RUBY_DESCRIPTION, digits.scan(/\d/)
#=> "ruby 1.9.2p180 (2011-02-18) [i386-mingw32]"
#=> ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]

ドキュメントを読み間違えていますか?他の Unicode 数字と一致しないのはなぜですか?\dまた、一致させる方法はありますか?

4

3 に答える 3

2

ruby-talkでBrian Candler が指摘:

  • \wは ASCII 文字と数字のみに一致し[[:alpha:]]、Unicode 文字の完全なセットに一致します。
  • \dは ASCII 数字のみに一致[[:digit:]]し、Unicode 番号の完全なセットに一致します。

したがって、動作は「一貫性」があり、Unicode 番号の簡単な回避策があります。同じ鬼車のドキュメント\wを読み進めると、次のテキストが表示されます。

\w  word character  
    Not Unicode: alphanumeric, "_" and multibyte char.  
    Unicode: General_Category -- (Letter|Mark|Number|Connector_Punctuation)

Ruby の実際の動作と上記の「非 Unicode」テキストを考慮すると、ドキュメントでは 2 つのモード (Unicode モードと非 Unicode モード) が記述されており、Ruby は非 Unicode モードで動作しているように見えます。

が完全な Unicode セットと一致しない理由はこれで説明\dできます。鬼車のドキュメントでは、非 Unicode モードの場合に何が一致するかを正確に説明していませんが、「Unicode」として文書化されている動作が予期されていないことがわかっています。

p "abç".scan(/\w/), "abç".scan(/[[:alpha:]]/)
#=> ["a", "b"]
#=> ["a", "b", "\u00E7"]

Ruby 正規表現で Unicode モードを有効にする方法 (あるとしても) を発見することは、読者の演習として残されて/u/\w/uます。(おそらく、鬼車用の特別なフラグを指定して Ruby を再コンパイルする必要があります。)

更新: 私がリンクした鬼車のドキュメントは、Ruby 1.9 に対して正確ではないようです。次の投稿を含む、このチケット ディスカッションを参照してください。

【成瀬由衣】「RE.txtはオリジナルの鬼車用です。Ruby1.9の正規表現用ではありません。独自のドキュメントが必要になるかもしれません。」
[Matz] 「私たちの鬼車は分岐したものです。geocities.jp にある元の鬼車は変更されていません。」

より良い参照: Ruby 1.9 の正規表現構文に関する公式ドキュメントは次のとおりです:
https://github.com/ruby/ruby/blob/trunk/doc/re.rdoc

于 2011-08-09T22:30:27.797 に答える
1

\p{N}代わりにUnicode文字クラスを試してください。これはすべてのUnicode桁に一致します。なぜ機能しないのかわかりません\d

于 2011-08-09T15:54:22.747 に答える
1

\dデフォルトでは ASCII 番号にのみ一致します。(直観に反する)(?u)構文を使用して、正規表現で Unicode マッチングを手動でオンにすることができます。

"".match(/(?u)\d/) # => #<MatchData "">

または、正規表現で「posix」または「unicode プロパティ」スタイルを使用できます。これにより、Unicode マッチングを手動で有効にする必要がなくなります。

/[[:digit:]]/ # posix style
/\p{Nd}/ # unicode property/category style

Ruby で Unicode 文字の高度なマッチングを行う方法の詳細については、次のブログ投稿を参照してください: https://idiosyncratic-ruby.com/30-regex-with-class.html

于 2016-03-26T14:24:34.740 に答える