で正規表現上のWikipediaの記事、それがいるようです[[:digit:]]
= [0-9]
= \d
。
それらが等しくない状況は何ですか?違いはなんですか?
いくつかの調査の後、1つの違いはブラケット式[:expr:]
がロケールに依存していることだと思います。
で正規表現上のWikipediaの記事、それがいるようです[[:digit:]]
= [0-9]
= \d
。
それらが等しくない状況は何ですか?違いはなんですか?
いくつかの調査の後、1つの違いはブラケット式[:expr:]
がロケールに依存していることだと思います。
回答:
はい、そうです[[:digit:]]
〜[0-9]
〜\d
(どこ〜手段aproximate)。
ほとんどのプログラミング言語(サポートされている場合)\d
≡ [[:digit:]]
(同一)。未満が一般的です(POSIXにはないが、それはGNUです)。\d
[[:digit:]]
grep -P
123456789 # Hindu-Arabic
アラビア数字
٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI
これのすべてが含まれることができるに[[:digit:]]
か\d
。
代わりに、[0-9]
通常はASCII数字のみ0123456789
です。
多くの言語があります:Perl、Java、Python、C。ここで[[:digit:]]
(および\d
)拡張された意味を要求します。たとえば、このperlコードは上記のすべての数字と一致します。
$ a='0123456789 ٠١٢٣٤٥٦٧٨٩ ۰۱۲۳۴۵۶۷۸۹ ߀߁߂߃߄߅߆߇߈߉ ०१२३४५६७८९'
$ echo "$a" | perl -C -pe 's/[^\d]//g;' ; echo
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९
これは、Numeric
およびのUnicodeプロパティを持つすべての文字を選択することと同等digits
です。
$ echo "$a" | perl -C -pe 's/[^\p{Nd}]//g;' ; echo
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९
どのgrepが再現できるか(pcreの特定のバージョンには、Perlとは異なる数値コードポイントの内部リストがある場合があります):
$ echo "$a" | grep -oP '\p{Nd}+'
0123456789
٠١٢٣٤٥٦٧٨٩
۰۱۲۳۴۵۶۷۸۹
߀߁߂߃߄߅߆߇߈߉
०१२३४५६७८९
表示するには[0-9]に変更します。
$ echo "$a" | grep -o '[0-9]\+'
0123456789
特定POSIX BREまたはEREの場合:(ないPOSIXではなく、GNUにあるサポートされていません)。
POSIXでは数字文字クラスに対応する必要があり、数字CはISO Cで文字0〜9以外の文字ではないことが必要です。だから、唯一のCにロケールすべてを、、とまったく同じ意味。何の可能性誤解を持っていない、より多くのユーティリティで利用可能で、それだけで意味するのが一般的です。いくつかのユーティリティでサポートされています。\d
grep -P
[[:digit:]]
[0-9]
[0123456789]
\d
[[:digit:]]
[0123456789]
[[:digit:]]
[0123456789]
\d
に関しては[0-9]
、範囲式の意味はCロケールのPOSIXによってのみ定義されます。他のロケールでは異なる場合があります(コードポイント順、照合順、またはその他の可能性があります)。
実装によっては、範囲をプレーンASCII順序(ksh93など)とは異なるものとして理解する場合があります。
$ LC_ALL=en_US.utf8 ksh -c 'a="'"$a"'";echo "${a//[0-9]}"'
۹ ߀߁߂߃߄߅߆߇߈߉ ९
そして、それが起こるのを待っているバグの確かな源です。
iswctype()
およびPOSIXユーティリティのBRE / ERE /ワイルドカードでは、[0-9]と[[:digit:]]は0123456789でのみ一致します。そして、それは標準の次のリビジョンで明示的に行われます
perl
の\d
Unicodeモードでは、他のスクリプトからの小数点以下の桁に一致します。ありがとう。PCREでは(*UCP)
、GNUのように、grep -Po '(*UCP)\d'
またはgrep -Po '(*UCP)[[:digit:]]
Unicodeプロパティに基づいたクラスを参照してください。
[:digit:]
ローカライズ、つまりユーザーが数字と見なすものを使用することを構文が示唆していることに同意します。私は決して使用しない[:digit:]
のと同じです、実際にので、[0-9]
必ず、私は0123456789に一致させたい、どのような場合とでは、私が一致することを意味したことがない٠١٢٣٤٥٦٧٨٩
、と私は1つは、小数点の桁に一致したいユースケースを考えることはできませんPOSIXユーティリティを使用したスクリプトで。zsh MLに関する現在の議論[:blank:]
も参照してください。これらの文字クラスは少し複雑です。
これは、数字の定義方法によって異なります。[0-9]
ASCIIのみになる傾向があります(または、ASCIIでもASCIIのスーパーセットでもないが、異なるビット表現(EBCDIC)のみのASCIIの場合と同じ10桁)。\d
一方、いずれかの単なる数字(のPerlの古いバージョン、またはでのPerlの最近のバージョン可能性があり/a
、正規表現フラグ有効)またはそれはのUnicodeの試合になる可能性\p{Digit}
はなく、数字の大きなセットである[0-9]
か/\d/a
のマッチ。
$ perl -E 'say "match" if 42 =~ m/\d/'
match
$ perl -E 'say "match" if "\N{U+09EA}" =~ m/\d/'
match
$ perl -E 'say "match" if "\N{U+09EA}" =~ m/\d/a'
$ perl -E 'say "match" if "\N{U+09EA}" =~ m/[0-9]/'
$
perldoc perlrecharclass
詳細については、問題の言語のドキュメントを参照して、その動作を確認してください。
しかし、待ってください、まだあります!ロケールは\d
一致するものによって異なる場合があるため、一致\d
するUnicodeの完全なセットよりも少ない数字に一致する可能性があり、(できれば、通常)も含まれ[0-9]
ます。これは、Cのisdigit(3)
([0-9]
)とisnumber(3)
([0-9
プラスロケールからのその他)の違いに似ています。
数字の値を取得するために呼び出しが行われる場合があり[0-9]
ます。
$ perl -MUnicode::UCD=num -E 'say num(4)'
4
$ perl -MUnicode::UCD=num -E 'say num("\N{U+09EA}")'
4
$
[0-9]
ます。
およびの異なる意味は[0-9]
、他の回答に示されています。ここで、正規表現エンジンの実装に違いを追加したいと思います。[[:digit:]]
\d
[[:digit:]] \d
grep -E ✓ ×
grep -P ✓ ✓
sed ✓ ×
sed -E ✓ ×
したがって、[[:digit:]]
常に動作します、\d
依存します。grepのマニュアルでは、ロケールにある[[:digit:]]
と述べられて0-9
いC
ます。
PS1:詳細をご存知の場合は、表を展開してください。
PS2:テストにはGNU grep 3.1およびGNU 4.4が使用されます。
grep
ありsed
、おそらくGNUバージョンと他のバージョンとの間に最大の違いがあります。この回答は、どのバージョンでgrep
あり、どのバージョンをsed
参照しているのかを説明していると、より役立つ場合があります。または、そのテーブルのソースが何であるかということです。2)そのテーブルは画像である必要があるものが含まれていないため、テキストに転写される可能性があります
re
モジュールは[[:digit:]]をサポートしていませんが、アドインライブラリregex
はそれをサポートしているので、常に少し動作するようにします。POSIXの苦情の状況では常に機能します。
理論的な違いは他の回答ですでに十分に説明されているので、実際の違いを説明するために残っています。
以下は、数字を照合するためのより一般的な使用例です。
多くの場合、いくつかの数字を圧縮したい場合、数字自体は扱いにくい形式のテキストファイルにあります。プログラムで使用するためにそれらを抽出します。おそらく、(ファイルを見て)数値形式と現在のロケールを伝えることができるので、ジョブが完了する限り、どのフォームを使用しても構いません。\d
必要なキーストロークが最も少ないため、非常に一般的に使用されています。
信頼されていないユーザー入力(Webフォームからの入力など)があり、予期しない内容が含まれていないことを確認する必要があります。データベースの数値フィールドに保存したり、シェルコマンドのパラメーターとして使用してサーバーで実行したい場合があります。この場合、[0-9]
最も制限的で予測可能なものなので、本当に必要です。
「危険」なものには使用しないデータが少しありますが、それが数値であるかどうかを知っておくと便利です。たとえば、プログラムでユーザーが住所を入力できるようにし、入力に家番号が含まれていない場合は、入力ミスを強調したい場合があります。この場合、あなたはおそらくできるだけ広くしたいので[[:digit:]]
、行く方法です。
これらは、数字照合の3つの最も一般的な使用例のようです。重要なものを見逃したと思われる場合は、コメントをお寄せください。