我对正则表达式的最大重复次数有疑问:{n}和{n,m}。
$ man grep
...
Repetition
A regular expression may be followed by one of several repetition operators:
...
{n} The preceding item is matched exactly n times.
{n,} The preceding item is matched n or more times.
{,m} The preceding item is matched at most m times. This is a GNU extension.
{n,m} The preceding item is matched at least n times, but not more than m times.
...
现在考虑一个测试文件:
$ cat ./sample.txt
1
12
123
1234
然后grep它为[0-9](数字)重复2次:
$ grep "[0-9]\{2\}" ./sample.txt
12
123
1234
?为什么这包括123和1234?
另外,我为同一个文本文件grep重复至少2次但不超过3次的数字:
$ grep "[0-9]\{2,3\}" ./sample.txt
12
123
1234
???为什么这会返回“1234”?
一个明显的解决方法是使用grep和reverse-grep来过滤掉过多的结果。例如,
$ grep "[0-9]\{2,\}" ./sample.txt | grep -v "[0-9]\{4,\}"
12
123
任何人都可以帮助我理解为什么{n}返回包含重复n次的模式的行?为什么{n,m}返回重复m次的模式?
答案 0 :(得分:4)
除非您锚定正则表达式,否则它们可以匹配字符串中的任何位置。
$ grep "[0-9]\{2\}" ./sample.txt
将匹配包含2位数的任何行。
使用^
强制表达式从行的开头开始,$
强制表达式与行尾相匹配。例如
$ grep '^[0-9]\{2\}$' ./sample.txt
# Using single quotes to avoid potential substitution issues. Hat tip to @ghoti
这应该只返回12
。
答案 1 :(得分:1)
可以在较长的文本中找到模式,也可以遵循相同的模式。对于grep,使用-o
选项查看正则表达式找到匹配的位置。在由两位数字组成的数字中,或者在一个长度为10位的数字中,可以找到两位数字。
另一个答案指向两个锚,但有一个单词边界标记\b
与边界位置匹配(如果使用)。这关闭了两端。不幸的是POSIX BRE(grep默认的正则表达式风格)并不支持这个,但在GNU sed中你可以启用Perl正则表达式并测试它:
grep -P '\b[0-9]{2}\b' file
只有grep
两个\<
和\>
匹配相同的位置:
grep '\<[0-9]\{2\}\>' file