匹配字符串中精确的数字位数

Rob*_*131 3 grep bash regular-expression

给定一个字符串,如何找出它恰好包含 7 个连续数字?

例如15050821505082_CSE_322但不是1505082115050821_CSE_322

我试过了

grep -Eq [0-9]{7} <<< "1505082" 
Run Code Online (Sandbox Code Playgroud)

返回0但是

grep -Eq [0-9]{7} <<< "15050821"` 
Run Code Online (Sandbox Code Playgroud)

也归来0

我做错了什么?

小智 5

是的,在(请引用正则表达式,否则它将被解释为 shell glob):

grep -Eq '[0-9]{7}' <<< "1505082"
Run Code Online (Sandbox Code Playgroud)

grep 匹配 7 位数字。您可以通过将 q 替换为 an 来查看匹配的内容o

$ grep -Eo '[0-9]{7}' <<< "1505082"; echo "$?"
1505082
0
Run Code Online (Sandbox Code Playgroud)

是的,它也会匹配这个:

$ grep -Eq '[0-9]{7}' <<< "150508299999"; echo "$?"
1505082
0
Run Code Online (Sandbox Code Playgroud)

它消除了所有的九。
问题是您正在进行非锚定匹配,它将匹配 7 位(或更多)数字。

您可以锚定

$ grep -Eq '^[0-9]{7}$' <<< "15050829999"; echo "$?"
1
Run Code Online (Sandbox Code Playgroud)

要匹配任何位置的 7 位数字并且后面或前面是非数字,您需要一个完全不同的锚点:

$ 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
Run Code Online (Sandbox Code Playgroud)

这些是前瞻匹配,一个是回顾:

(?<=^|[^0-9])
Run Code Online (Sandbox Code Playgroud)

匹配字符串 ( ) 的开头^或非数字。另一个是前瞻:

(?=[^0-9]|$)
Run Code Online (Sandbox Code Playgroud)

匹配非数字或字符串结尾。


使用更简单的正则表达式的唯一其他替代方法Extended是提取任意7(或更多)数字,然后确认它恰好是 7 位数字:

$ echo "150508299_CSE_322" | 
          grep -oE '[0-9]{7,}' | 
                  grep -qE '^[0-9]{7}$'; echo "$?"
1
Run Code Online (Sandbox Code Playgroud)