我正在尝试grep,以获得输入字符串允许的最大重复次数,但似乎无法使其正常工作。
输入文件有三行,分别重复3、5和7次"pq“。>=3、>=5表达式运行良好,但“介于3和5之间”表达式{3,5}也显示了具有七次重复的行。
DEV /> cat input.txt
pq -- One occurance of pq
pqpqpqpqpq -five occurances of pq
pqpqpqpqpqpqpq -- seven occurances of pq
DEV /> grep "\(pq\)\{3,\}" input.txt
pqpqpqpqpq -five occurances of pq
pqpqpqpqpqpqpq -- seven occurances of pq
DEV /> grep "\(pq\)\{5\}" input.txt
pqpqpqpqpq -five occurances of pq
pqpqpqpqpqpqpq -- seven occurances of pq
DEV /> grep "\(pq\)\{3,5\}" input.txt
pqpqpqpqpq -five occurances of pq
pqpqpqpqpqpqpq -- seven occurances of pq是我做错了什么,还是这是预期中的行为?
如果这是预期的行为(因为具有7个PQ的串具有3-5个PQ),
1)在什么情况下最大重复次数适用?{3,5}和{3,}(大于3)之间的差异是什么?
2)我可以用"^“锚定我的正则表达式,但是如果我的字符串不是以"pq”结尾并且有更多的文本怎么办?
发布于 2011-04-18 06:06:05
如果一条线有七个重复的东西,那么它也包含该东西的3-5个重复,并且在几个点上,不少于。
如果希望锚定匹配,请使用匹配锚点。否则,他们当然不是。
/X{3,}/和/X{3,5}/之间的实际区别在于它匹配字符串的长度-匹配的范围(或跨度)。如果您所寻找的只是一个布尔型的yes/no响应,并且您的模式中没有进一步的内容,那么这并没有太大的区别;事实上,如果一个相当聪明的正则表达式引擎知道这样做是安全的,那么它将提前返回。
查看差异的一种方法是使用GNU grep的-o或‑‑only‐matching选项。观看:
$ echo 123456789 | egrep -o '[0-9]{3}'
123
456
789
$ echo 123456789 | egrep -o '[0-9]{3,}'
123456789
$ echo 123456789 | egrep -o '[0-9]{3,5}'
12345
6789
$ echo 123456789 | egrep -o '[0-9]{3,5}[2468]'
123456
$ echo 123456790 | egrep -o '[0-9]{3,5}[13579]'
12345
6789为了理解最后两个是如何工作的,跟踪正则表达式引擎的尝试是很有用的,包括回溯步骤。您可以通过以下方式使用Perl完成此操作:
$ perl -Mre=debug -le 'print $& while 1234567890 =~ /\d{3,5}[13579]/g'
Compiling REx "\d{3,5}[13579]"
Final program:
1: CURLY {3,5} (4)
3: DIGIT (0)
4: ANYOF[13579][] (15)
15: END (0)
stclass DIGIT minlen 4
Matching REx "\d{3,5}[13579]" against "1234567890"
Matching stclass DIGIT against "1234567" (7 chars)
0 <> <1234567890> | 1:CURLY {3,5}(4)
DIGIT can match 5 times out of 5...
5 <12345> <67890> | 4: ANYOF[13579][](15)
failed...
4 <1234> <567890> | 4: ANYOF[13579][](15)
5 <12345> <67890> | 15: END(0)
Match successful!
12345
Matching REx "\d{3,5}[13579]" against "67890"
Matching stclass DIGIT against "67" (2 chars)
5 <12345> <67890> | 1:CURLY {3,5}(4)
DIGIT can match 5 times out of 5...
10 <1234567890> <> | 4: ANYOF[13579][](15)
failed...
9 <123456789> <0> | 4: ANYOF[13579][](15)
failed...
8 <12345678> <90> | 4: ANYOF[13579][](15)
9 <123456789> <0> | 15: END(0)
Match successful!
6789
Freeing REx: "\d{3,5}[13579]"当你对比赛后的内容有额外的限制时,那么你选择哪种类型的重复可以产生很大的不同。在这里,我将对每个匹配的结束位置施加一个限制,即它需要在奇数位之前结束:
$ perl -le 'print $& while 1234567890 =~ /\d{3}(?=[13579])/g'
234
678
$ perl -le 'print $& while 1234567890 =~ /\d{3,5}(?=[13579])/g'
1234
5678
% perl -le 'print $& while 1234567890 =~ /\d{3,}(?=[13579])/g'
12345678因此,当你有事情必须在之后发生时,它可以产生很大的不同。当你只是在决定整行是否与某项匹配时,它可能不那么重要。
发布于 2011-04-18 06:06:19
这是预期的行为。字符串“您可能希望尝试锚定您的正则表达式,如^\(pq\)\{3,5\}$。
编辑以匹配已编辑的问题:
^\(pq\){3,5}\($|[^p]|p$|p[^q]\)。它匹配3-5个“pq”,后面紧跟行尾或除“p”或“p”之外的任何字符,后跟行尾或"p"-followed-by-any-character-other-than-"q".https://stackoverflow.com/questions/5696750
复制相似问题