1小时前我一直在问一个关于使用 grep 命令的正则表达式的类似问题,请原谅我,如果首选的选择是在同一个线程中发布,如果是这种情况,我下次会这样做。
它可能看起来像是基本的合成,但我试图理解正则表达式识别模式是如何工作的,而我得到的结果似乎与我正在阅读的有关它们的手册相矛盾(我很可能没有正确解释这些材料)。
一个文件包含以下单词列表:
mael@mael-HP:~/repertoireVide$ cat MySQLServ
remembré
emmuré
emmené
dilemmes
jumeaux
écrémage
emmena
emmailloter
flemmard
以下命令给出输出
mael@mael-HP:~/repertoireVide$ grep -r 'emm*[a-f].[^ta]$'
MySQLServ:remembré
MySQLServ:emmené
MySQLServ:flemmard
我想知道为什么grep
不匹配单词“emmailloter”,因为“emmailloter”:
- 包含“em”
- 之后在 [af] 之间包含一个字符:'a'
- “我”满足“.”成分
- 不以字符“t”或“a”结尾
谢谢。
答案1
该字emmailloter
包含的内容远多于和i
匹配的位之间的内容。该模式仅匹配单个字符,因此如果您想在末尾和之间匹配多个字符,则必须允许多个字符:[a-f]
[^ta]$
.
emma
r
emm*[a-f]..*[^ta]$
随着grep -E
(启用扩展正则表达式),..*
可以写成.+
,即“匹配至少一个字符”。该表达式..*
读作“匹配一个字符,然后可能匹配更多字符”。同样,如果使用 ,则emm*
可以替换为em+
,即“e
后跟至少一个” 。m
grep -E
这将匹配字符串
blop-emmmmmmmmma-blarg-b
^^^^^^^^^^^^^^^^^^^
1111111111233333334
1: emm*
2: [a-f]
3: ..*
4: [^ta]$
(上面字符表示的匹配部分^
),例如,还有emmailloter
:
emmailloter
^^^^^^^^^^^
11123333334
测试:
$ grep -E 'emm*[a-f].+[^ta]$' MySQLServ
remembré
emmené
emmailloter
flemmard
请注意,对于单词remembré
,匹配将是
remembré
^^^^^^^
1123334
不是
remembré
^^^^^
11234
一种方法是可视化匹配使用sed
:
$ sed -n -E 's/(emm*)([a-f])(.+)([^ta]$)/(\1)(\2)(\3)(\4)/p' MySQLServ
r(em)(e)(mbr)(é)
(emm)(e)(n)(é)
(emm)(a)(illote)(r)
fl(emm)(a)(r)(d)
这只会打印匹配的行,正则表达式的每个匹配部分都放在括号中。这还假设您正在使用sed
可用于匹配法语字符的实现,并且已正确设置语言环境环境变量来执行此操作。
将其与原始表达式产生的结果进行比较:
$ sed -n -E 's/(emm*)([a-f])(.)([^ta]$)/(\1)(\2)(\3)(\4)/p' MySQLServ
rem(em)(b)(r)(é)
(emm)(e)(n)(é)
fl(emm)(a)(r)(d)