试图连续重复的字母出现两次或三次。无法找到使用ERE
使用量词和捕获组的方法$ grep --version | head -n1
grep (GNU grep) 2.25
$ # consecutive repeated letters occurring twice
$ grep -m5 -xiE '[a-z]*([a-z])\1[a-z]*[a-z]*([a-z])\2[a-z]*' /usr/share/dict/words
Abbott
Annabelle
Annette
Appaloosa
Appleseed
$ # no output for this, why?
$ grep -m5 -xiE '([a-z]*([a-z])\2[a-z]*){2}' /usr/share/dict/words
适用于-P
但
$ grep -m5 -xiP '([a-z]*([a-z])\2[a-z]*){2}' /usr/share/dict/words
Abbott
Annabelle
Annette
Appaloosa
Appleseed
$ grep -m5 -xiP '([a-z]*([a-z])\2[a-z]*){3}' /usr/share/dict/words
Chattahoochee
McConnell
Mississippi
Mississippian
Mississippians
感谢Casimir et Hippolyte提出更简单的输入和正则表达式来测试此行为
$ echo 'aazbb' | grep -E '(([a-z])\2[a-z]*){2}' || echo 'No match'
aazbb
$ echo 'aazbbycc' | grep -E '(([a-z])\2[a-z]*){2}([a-z])\3[a-z]*' || echo 'No match'
aazbbycc
$ echo 'aazbbycc' | grep -P '(([a-z])\2[a-z]*){3}' || echo 'No match'
aazbbycc
$ # failing case
$ echo 'aazbbycc' | grep -E '(([a-z])\2[a-z]*){3}' || echo 'No match'
No match
与sed
同样的行为
$ sed --version | head -n1
sed (GNU sed) 4.2.2
$ echo 'aazbb' | sed -E '/(([a-z])\2[a-z]*){2}/! s/.*/No match/'
aazbb
$ echo 'aazbbycc' | sed -E '/(([a-z])\2[a-z]*){2}([a-z])\3[a-z]*/! s/.*/No match/'
aazbbycc
$ # failing case
$ echo 'aazbbycc' | sed -E '/(([a-z])\2[a-z]*){3}/! s/.*/No match/'
No match
相关搜索链接,我检查了其中一些,但没有得到任何接近这个问题
如果在较新版本的grep
或sed
中解决此问题,请与我们联系。此外,如果在非GNU实现中看到问题
答案 0 :(得分:2)
我认为 -E
不允许Quantifiers
,这就是为什么它仅适用于-P
匹配2个或更多连续的重复字母组:
grep -P '(?:([a-z])\1*([a-z])\2){1}' /usr/share/dict/words
匹配3个或更多连续的重复字母组:
grep -P '(?:([a-z])\1*([a-z])\2){2}' /usr/share/dict/words
选项:
-P, --perl-regexp PATTERN is a Perl regular expression
答案 1 :(得分:0)
更新
搜索完之后,我在我的windows box上安装了gnugrep32,然后运行了
一些测试:
我是从旧的SO帖子中读到的:
非贪婪匹配不是grep
支持的扩展正则表达式语法的一部分
因此,我们使用[a-z]{0,20}
作为测试,而不是[a-z]*
或[a-z]*?
,其中?
被忽略(wtf?)
以下是使用整体(){n}
的增量测试,以了解 STOPS BACKTRACKING 之前的距离
进入帧。
最近工作
(([a-z])\2[a-z]{0,20}){1} len = 2 rr
(([a-z])\2[a-z]{0,20}){2} len = 4 rrrr
(([a-z])\2[a-z]{0,20}){3} len = 25 rrrrrrrrrrrrrrrrrrrrrrrrr
(([a-z])\2[a-z]{0,20}){4} len = 47 rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
(([a-z])\2[a-z]{0,20}){5} len = 69 rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
(([a-z])\2[a-z]{0,20}){6} len = 91 rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
从{3}
到{6}
,delta长度等于22.
这恰好是捕获帧表达式([a-z])\2[a-z]{0,20}
的全长
当它没有回溯到之前的帧时。
结论是它会在2帧后自动停止回溯。
例如,在20帧中,它变为16,并且发现它无法匹配。 然后它回到第1帧并在那里进行调整并在agaqin上尝试。
为什么会这样。
然而,它现在已经消耗了大量的记忆,臃肿的猪必须放松它
这可能需要永远使用这个旧的古老的实用程序
嘿,最好把它限制在2帧。
当然,由于贪婪量词(([a-z])\2[a-z]*){3}
,*
没有测试用例
如果它们都是[a-z],则会消耗第二帧上的整行,甚至从不使用
开始第三帧。
答案 2 :(得分:0)
$ # no output for this, why?
$ grep -m5 -xiE '([a-z]*([a-z])\2[a-z]*){2}' /usr/share/dict/words
因为您搜索内部具有(至少)双字母的双组(两次相同)。类似于abbcabbc
[(...) = "abbc"
2次]而不是2(最终类似)的内容,其中每个内部都有一个双字母,如abbcdeef
。
有2个后退参考:
$ grep -iE '[a-z]*([a-z])\1{1,}[a-z]*([a-z])\2{1,}[a-z]*`
答案 3 :(得分:0)
我提交了一个问题 https://debbugs.gnu.org/cgi/bugreport.cgi?bug=26864,现在更新了手册以反映此类问题。
来自https://www.gnu.org/software/grep/manual/grep.html#Known-Bugs:
<块引用>反向引用会大大减慢匹配速度,因为它们会产生成倍数的匹配可能性,这会消耗时间和内存进行探索。此外,反向引用的 POSIX 规范有时也不清楚。此外,许多正则表达式实现都存在反向引用错误,这些错误可能导致程序返回错误答案甚至崩溃,而修复这些错误的优先级通常较低:例如,截至 2020 年,GNU C library bug database 包含反向引用错误 52、10844、11053、24269 和 25322,几乎没有即将修复的迹象。幸运的是,反向引用很少有用,在实际应用中避免它们应该不难。