air*_*ulk 9 regex unix bash grep
UPD:根据埃德·莫顿的回答,这个问题不仅仅与选项有关-E。
阅读 Brian W. Kernighan 和 Rob Pike 撰写的《Unix 编程环境》。
进行一项练习,应使用 查找单词列表中的所有回文grep -E。
我能够在网上找到并理解的最简洁的解决方案是
'^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1$',它应该找到最多 11 个字符的所有回文。
For some reason though, grep in my terminal gives me results that I can't explain:
me@machine:~/test$ cat sample
a
ab
abba
abcdef
abcba
zufolo
me@machine:~/test$ grep -E '^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1$' sample
a
abba
abcba
zufolo
me@machine:~/test$ grep -E '^(.?)(.?)(.?)(.?).?\4\3\2\1$' sample
a
abba
abcba
Run Code Online (Sandbox Code Playgroud)
Why would it add zufolo to the results (while not coloring any matches as it does with the actual palindromes)? Why does zufolo disappear when I reduce the regex to up to 9 characters?
output
Does it have anything to do with my setup (the most standard one)?
me@machine:~/test$ ls -l /proc/$$/exe
lrwxrwxrwx 1 me me 0 jan 15 18:37 /proc/3528/exe -> /usr/bin/bash
me@machine:~/test$ cat /proc/version
Linux version 6.5.0-14-generic (buildd@lcy02-amd64-110) (x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0, GNU ld (GNU Binutils for Ubuntu) 2.38) #14~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Mon Nov 20 18:15:30 UTC 2
Run Code Online (Sandbox Code Playgroud)
P.S. zufolo is from wamerican-insane where I'm actually testing it. There are plenty of others like xenian, tartar.
I tried researching online, modifying regex, but can't get my head around this one.
奇怪的是,从正则表达式的末尾删除$(即减少限制)会产生更少的匹配项,这与它应该做的相反:
$a)在正则表达式末尾添加:
$ grep -E '^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1$' sample
a
abba
abcba
zufolo
Run Code Online (Sandbox Code Playgroud)
b) 正则$表达式末尾没有 :
$ grep -E '^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1' sample
a
abba
abcba
Run Code Online (Sandbox Code Playgroud)
不仅仅是 GNU grep 的行为很奇怪,GNU sed 在匹配时也有与问题相同的行为,sed -nE '/.../p' sample就像 GNUgrep所做的那样,并且如果我们只是进行匹配与进行匹配 + 替换,sed 的行为会有所不同。
例如,这里sed进行匹配+替换,其行为方式与grep上面相同:
$a)在正则表达式末尾添加:
$ sed -nE 's/^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1$/&/p' sample
a
abba
abcba
zufolo
Run Code Online (Sandbox Code Playgroud)
b) 正则$表达式末尾没有 :
$ sed -nE 's/^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1/&/p' sample
a
abba
abcba
Run Code Online (Sandbox Code Playgroud)
但这里 sed 只是进行匹配,其行为与上述任何一个都不同:
a) 在$正则表达式的末尾添加 (注意ab输出中的额外内容):
$ sed -nE '/^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1$/p' sample
a
ab
abba
abcba
zufolo
Run Code Online (Sandbox Code Playgroud)
b) 正则$表达式末尾没有 ”(注意输出中的额外ab和):abcdef
$ sed -nE '/^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1/p' sample
a
ab
abba
abcdef
abcba
zufolo
Run Code Online (Sandbox Code Playgroud)
另外有趣的是:
$ sed -nE 's/^(.?)(.?)(.?)(.?)(.?).?\5\4\3\2\1$/<&>/p' sample
Run Code Online (Sandbox Code Playgroud)
输出:
<a>
<abba>
<abcba>
<>zufolo
Run Code Online (Sandbox Code Playgroud)
最后一行意味着正则表达式显然匹配行的开头并忽略$正则表达式中存在的字符串结尾元字符!
不过,奇怪的行为不仅仅与 using 相关-E,如果我删除-E并仅使用符合 POSIX 的 BRE,那么:
$a)在正则表达式末尾添加:
$ grep '^\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\).\{0,1\}\5\4\3\2\1$' sample
a
abba
abcba
zufolo
Run Code Online (Sandbox Code Playgroud)
$ sed -n 's/^\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\).\{0,1\}\5\4\3\2\1$/&/p' sample
a
abba
abcba
zufolo
Run Code Online (Sandbox Code Playgroud)
b) 正则$表达式末尾没有 :
$ grep '^\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\).\{0,1\}\5\4\3\2\1' sample
a
abba
abcba
Run Code Online (Sandbox Code Playgroud)
$ sed -n 's/^\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\).\{0,1\}\5\4\3\2\1/&/p' sample
a
abba
abcba
Run Code Online (Sandbox Code Playgroud)
同样,在下面的 sed 中进行匹配的行为与上面的 sed match+replacements 不同:
$a)在正则表达式末尾添加:
$ sed -n '/^\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\).\{0,1\}\5\4\3\2\1$/p' sample
a
ab
abba
abcba
zufolo
Run Code Online (Sandbox Code Playgroud)
b) 正则$表达式末尾没有 :
$ sed -n '/^\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\)\(.\{0,1\}\).\{0,1\}\5\4\3\2\1/p' sample
a
ab
abba
abcdef
abcba
zufolo
Run Code Online (Sandbox Code Playgroud)
上面显示,给定相同的正则表达式,sed 显然会匹配不同的字符串,具体取决于它是否进行替换。
因此,没有 .gnu 扩展名的 GNU grep 和 GNU sed 似乎存在错误-E。或者也许以上只是给定这些正则表达式的未定义行为,因此任何 grep 或 sed 都可以对它们做任何他们喜欢的事情。
$ grep --version | head -1
grep (GNU grep) 3.11
$ sed --version | head -1
sed (GNU sed) 4.9
Run Code Online (Sandbox Code Playgroud)