ERE - 将量词添加到具有内部组和反向引用的组

Sun*_*eep 14 regex grep pcre gnu sed

试图连续重复的字母出现两次或三次.无法使用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
Run Code Online (Sandbox Code Playgroud)


与工作-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
Run Code Online (Sandbox Code Playgroud)


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

同样的行为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
Run Code Online (Sandbox Code Playgroud)


相关的搜索链接,我检查了其中一些,但没有得到任何接近这个问题

如果在较新版本中解决了这个问题,grep或者sed让我知道.此外,如果在非GNU实现中看到该问题

Sun*_*eep 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 库错误数据库包含反向引用bug 5210844110532426925322,几乎没有迹象表明即将修复。幸运的是,反向引用很少有用,在实际应用中避免它们应该不成问题。