GNU/Linux >> Linux の 問題 >  >> Linux

[0-9]、[[:digit:]]とDの違いは?

正規表現に関するウィキペディアの記事では、[[:digit:]]のようです。 =[0-9] =d

それらが等しくない状況は何ですか?違いは何ですか?

いくつかの調査の結果、1つの違いは、ブラケット式[:expr:]であると思います。 ロケールに依存します。

承認された回答:

はい、[[:digit:]]です 〜[0-9]d (〜は概算を意味します。)
ほとんどのプログラミング言語(サポートされている場合)

d ≡ `[[:digit:]]`            # (is identical to, it is a short hand for).  

d [[:digit:]]より少ないインスタンスに存在します (grep -Pで利用可能 ただし、POSIXにはありません)。

Unicode数字

[UNICODEには多くの数字](http://www.fileformat.info/info/unicode/category/Nd/list.htm)があります。例:

123456789 # Hindu-Arabic アラビア数字
٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI

これらはすべて[[:digit:]]に含まれている可能性があります またはd 、および[0-9]の場合もあります 。

POSIX

特定のPOSIXBREまたはEREの場合:
d サポートされていません(POSIXにはありませんが、GNU grep -Pにあります )。 [[:digit:]] POSIXでは数字の文字クラスに対応する必要があります。ISOCでは0から9までの文字である必要があります。したがって、Cロケールのみ すべての[0-9][0123456789]d および[[:digit:]] まったく同じ意味です。 [0123456789] 誤解の可能性はありません、[[:digit:]] より多くのユーティリティで利用可能であり、場合によっては[0123456789]のみを意味します 。 d いくつかのユーティリティでサポートされています。

[0-9]について 、範囲式の意味は、CロケールのPOSIXによってのみ定義されます。他のロケールでは、異なる場合があります(コードポイントの順序、照合の順序など)。

[0123456789]

すべてのASCII数字の最も基本的なオプション。
常に有効、(AFAICT)失敗する既知のインスタンスはありません。

英語の数字にのみ一致します:0123456789

[0-9]

一般的に、[0-9] ASCII数字のみです0123456789
これは、場合によっては非常に誤りです。たとえば、「C」(2020年6月)システムではないロケールのLinux:

仮定:

str='0123456789 ٠١٢٣٤٥٦٧٨٩ ۰۱۲۳۴۵۶۷۸۹ ߀߁߂߃߄߅߆߇߈߉ ०१२३४५६७८९'

grepをお試しください それらのほとんどを許可することを発見するために:

$ echo "$str" | grep -o '[0-9]+'
0123456789
٠١٢٣٤٥٦٧٨
۰۱۲۳۴۵۶۷۸
߀߁߂߃߄߅߆߇߈
०१२३४५६७८

そのsedにはいくつかの問題があります。 0123456789のみを削除する必要があります ただし、ほとんどすべての桁が削除されます。つまり、ほとんどの数字を受け入れますが、一部の9桁は受け入れません(???):

$ echo "$str" | sed 's/[0-9]{1,}//g'
 ٩ ۹ ߉ ९

そのexprでさえsedの同じ問題に苦しんでいます:

expr "$str" : '([0-9 ]*)'             # also matching spaces.
0123456789 ٠١٢٣٤٥٦٧٨

そしてまたed

printf '%sn' 's/[0-9]/x/g' '1,p' Q | ed -v <(echo "$str")
105
xxxxxxxxxx xxxxxxxxx٩ xxxxxxxxx۹ xxxxxxxxx߉ xxxxxxxxx९

[[:digit:]]

多くの言語があります:Perl、Java、Python、C。[[:digit:]] (およびd )拡張された意味を要求します。たとえば、このPerlコードは上からのすべての数字と一致します:

$ str='0123456789 ٠١٢٣٤٥٦٧٨٩ ۰۱۲۳۴۵۶۷۸۹ ߀߁߂߃߄߅߆߇߈߉ ०१२३४५६७८९'

$ echo "$str" | perl -C -pe 's/[^d]//g;' ; echo
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९

これは、NumericのUnicodeプロパティを持つすべての文字を選択するのと同じです。 およびdigits

$ echo "$str" | perl -C -pe 's/[^p{Nd}]//g;' ; echo
0123456789٠١٢٣٤٥٦٧٨٩۰۱۲۳۴۵۶۷۸۹߀߁߂߃߄߅߆߇߈߉०१२३४५६७८९

どのgrepを再現できるか(特定のバージョンのpcreには、Perlとは異なる数値コードポイントの内部リストがある場合があります):

$ echo "$str" | grep -oP 'p{Nd}+'
0123456789
٠١٢٣٤٥٦٧٨٩
۰۱۲۳۴۵۶۷۸۹
߀߁߂߃߄߅߆߇߈߉
०१२३४५६७८९

シェル

一部の実装では、範囲がプレーンASCII順序(たとえばksh93)とは異なるものであると理解する場合があります(2018年5月バージョン(AT&T Research)93u + 2012-08-01でテストした場合):

$ LC_ALL=en_US.utf8 ksh -c 'echo "${1//[0-9]}"' sh "$str"
  ۹ ߀߁߂߃߄߅߆߇߈߉ ९

現在(2020年6月)、debianの同じパッケージksh93(同じバージョンsh(AT&T Research)93u + 2012-08-01):

$ LC_ALL=en_US.utf8 ksh -c 'echo "${1//[0-9]}"' sh "$str"

 ٩ ۹ ߉ ९

そして、それはバグが発生するのを待っている確かな原因だと私には思えます。

関連:Bash演算子の違い[[vs [vs(vs((?
Linux
  1. ログインシェルと非ログインシェルの違いは?

  2. Bash の ${} と $() の違い

  3. cgroup と名前空間の違い

  1. 2>&-、2> / dev / null、|&、&> / dev/nullと>/dev / null 2>&1の違いは?

  2. Sudo Su –とSudo Su —の違いは何ですか?

  3. EotとEofの違いは?

  1. GtkとQtアプリケーションの違いは?

  2. ブロックサイズとクラスターサイズの違いは?

  3. 配管とコマンド拡張の違いは?