web-dev-qa-db-ja.com

文字列の正確な桁数を照合する

文字列が与えられた場合、正確に7桁の数字が含まれていることをどのように確認できますか?

1505082または1505082_CSE_322など。ただし15050821または15050821_CSE_322は不可

私はもう試した

grep -Eq [0-9]{7} <<< "1505082" 

0を返しますが

grep -Eq [0-9]{7} <<< "15050821"` 

0も返します。

私は何を間違っていますか?

1
Robur_131

はい、(正規表現を引用してください。そうしないと、シェルグロブとして解釈されます):

grep -Eq '[0-9]{7}' <<< "1505082"

grepは7桁と一致しています。 qをoに置き換えることで、何が一致しているかを確認できます。

$ grep -Eo '[0-9]{7}' <<< "1505082"; echo "$?"
1505082
0

そして、はい、それもこれと一致します:

$ grep -Eq [0-9]{7} <<< "150508299999"; echo "$?"
1505082
0

それはすべてのナインを削除しました。
問題は、アンカーされていない一致を作成していて、7桁(またはそれ以上)の番号と一致することです。

アンカーで次のことができます:

$ grep -Eq '^[0-9]{7}$' <<< "15050829999"; echo "$?"
1

7桁の数字anywhereを照合し、その後に数字以外を付けるには、完全に異なるアンカーが必要です。

$ grep -oP '(?<=^|[^0-9])[0-9]{7}(?=[^0-9]|$)' <<< "1505082"; echo $?
1505082
0

$ grep -oP '(?<=^|[^0-9])[0-9]{7}(?=[^0-9]|$)' <<< "1505082_CSE_322"; echo $?
1505082
0

$ grep -oP '(?<=^|[^0-9])[0-9]{7}(?=[^0-9]|$)' <<< "1505082999_CSE_322"; echo $?
0

それらは先読みのマッチであり、1つはルックバックです。

(?<=^|[^0-9])

文字列の先頭(^)または数字以外のいずれかに一致します。もう1つは先読みです。

(?=[^0-9]|$)

非数字または文字列の末尾のいずれかに一致します。


より単純なExtended正規表現を使用する他の唯一の代替方法は、7(またはそれ以上)の数字の実行を抽出し、それが正確に7桁であることを確認することです。

$ echo "150508299_CSE_322" | 
          grep -oE '[0-9]{7,}' | 
                  grep -qE '^[0-9]{7}$'; echo "$?"
1
2
Isaac

grepで事態が複雑になった場合は、いつでもegrepを使用したり、linux/unixシステムで利用可能なプログラミング言語を使用して、match/regexpを支援したりできます。

システムにPerlまたはRubyがある場合は、1行で実行できます。

echo 1234567| Ruby -lne 'print if /^\d{7}$/'

echo 1234567| Perl -lne 'print if /^\d{7}$/'

または

cat file.txt | Ruby -lne 'print if /^\d{7}$/'

0
ronnie bermejo