sha*_*n11 3 grep regular-expression
使用grep -E
和正则表达式我需要找到包含所有一组字符的单词,没有特定的顺序。例如,包含所有元音的单词 (aeiou) 但是元音可以以任何顺序出现在单词中。
小智 7
此规则“aeiou
以某种顺序包含所有内容”不能用grep -E
合理大小的 POSIX 扩展正则表达式 ( ) 表示。
这是一个大的,列出了 aeiou 的所有 120 个排列作为替代:
a.*e.*i.*o.*u|a.*e.*i.*u.*o|a.*e.*o.*i.*u|a.*e.*o.*u.*i|a.*e.*u.*i.*o|a.*e.*u.*o.*i|a.*i.*e.*o.*u|a.*i.*e.*u.*o|a.*i.*o.*e.*u|a.*i.*o.*u.*e|a.*i.*u.*e.*o|a.*i.*u.*o.*e|a.*o.*e.*i.*u|a.*o.*e.*u.*i|a.*o.*i.*e.*u|a.*o.*i.*u.*e|a.*o.*u.*e.*i|a.*o.*u.*i.*e|a.*u.*e.*i.*o|a.*u.*e.*o.*i|a.*u.*i.*e.*o|a.*u.*i.*o.*e|a.*u.*o.*e.*i|a.*u.*o.*i.*e|e.*a.*i.*o.*u|e.*a.*i.*u.*o|e.*a.*o.*i.*u|e.*a.*o.*u.*i|e.*a.*u.*i.*o|e.*a.*u.*o.*i|e.*i.*a.*o.*u|e.*i.*a.*u.*o|e.*i.*o.*a.*u|e.*i.*o.*u.*a|e.*i.*u.*a.*o|e.*i.*u.*o.*a|e.*o.*a.*i.*u|e.*o.*a.*u.*i|e.*o.*i.*a.*u|e.*o.*i.*u.*a|e.*o.*u.*a.*i|e.*o.*u.*i.*a|e.*u.*a.*i.*o|e.*u.*a.*o.*i|e.*u.*i.*a.*o|e.*u.*i.*o.*a|e.*u.*o.*a.*i|e.*u.*o.*i.*a|i.*a.*e.*o.*u|i.*a.*e.*u.*o|i.*a.*o.*e.*u|i.*a.*o.*u.*e|i.*a.*u.*e.*o|i.*a.*u.*o.*e|i.*e.*a.*o.*u|i.*e.*a.*u.*o|i.*e.*o.*a.*u|i.*e.*o.*u.*a|i.*e.*u.*a.*o|i.*e.*u.*o.*a|i.*o.*a.*e.*u|i.*o.*a.*u.*e|i.*o.*e.*a.*u|i.*o.*e.*u.*a|i.*o.*u.*a.*e|i.*o.*u.*e.*a|i.*u.*a.*e.*o|i.*u.*a.*o.*e|i.*u.*e.*a.*o|i.*u.*e.*o.*a|i.*u.*o.*a.*e|i.*u.*o.*e.*a|o.*a.*e.*i.*u|o.*a.*e.*u.*i|o.*a.*i.*e.*u|o.*a.*i.*u.*e|o.*a.*u.*e.*i|o.*a.*u.*i.*e|o.*e.*a.*i.*u|o.*e.*a.*u.*i|o.*e.*i.*a.*u|o.*e.*i.*u.*a|o.*e.*u.*a.*i|o.*e.*u.*i.*a|o.*i.*a.*e.*u|o.*i.*a.*u.*e|o.*i.*e.*a.*u|o.*i.*e.*u.*a|o.*i.*u.*a.*e|o.*i.*u.*e.*a|o.*u.*a.*e.*i|o.*u.*a.*i.*e|o.*u.*e.*a.*i|o.*u.*e.*i.*a|o.*u.*i.*a.*e|o.*u.*i.*e.*a|u.*a.*e.*i.*o|u.*a.*e.*o.*i|u.*a.*i.*e.*o|u.*a.*i.*o.*e|u.*a.*o.*e.*i|u.*a.*o.*i.*e|u.*e.*a.*i.*o|u.*e.*a.*o.*i|u.*e.*i.*a.*o|u.*e.*i.*o.*a|u.*e.*o.*a.*i|u.*e.*o.*i.*a|u.*i.*a.*e.*o|u.*i.*a.*o.*e|u.*i.*e.*a.*o|u.*i.*e.*o.*a|u.*i.*o.*a.*e|u.*i.*o.*e.*a|u.*o.*a.*e.*i|u.*o.*a.*i.*e|u.*o.*e.*a.*i|u.*o.*e.*i.*a|u.*o.*i.*a.*e|u.*o.*i.*e.*a
Run Code Online (Sandbox Code Playgroud)
这是一个更短但由于嵌套而难以遵循的:
a.*(e.*(i.*[ou]|o.*[iu]|u.*[io])|i.*(e.*[ou]|o.*[eu]|u.*[eo])|o.*(e.*[iu]|i.*[eu]|u.*[ei])|u.*(e.*[io]|i.*[eo]|o.*[ei]))|e.*(a.*(i.*[ou]|o.*[iu]|u.*[io])|i.*(a.*[ou]|o.*[au]|u.*[ao])|o.*(a.*[iu]|i.*[au]|u.*[ai])|u.*(a.*[io]|i.*[ao]|o.*[ai]))|i.*(a.*(e.*[ou]|o.*[eu]|u.*[eo])|e.*(a.*[ou]|o.*[au]|u.*[ao])|o.*(a.*[eu]|e.*[au]|u.*[ae])|u.*(a.*[eo]|e.*[ao]|o.*[ae]))|o.*(a.*(e.*[iu]|i.*[eu]|u.*[ei])|e.*(a.*[iu]|i.*[au]|u.*[ai])|i.*(a.*[eu]|e.*[au]|u.*[ae])|u.*(a.*[ei]|e.*[ai]|i.*[ae]))|u.*(a.*(e.*[io]|i.*[eo]|o.*[ei])|e.*(a.*[io]|i.*[ao]|o.*[ai])|i.*(a.*[eo]|e.*[ao]|o.*[ae])|o.*(a.*[ei]|e.*[ai]|i.*[ae]))
Run Code Online (Sandbox Code Playgroud)
两者都假设您要搜索的单词位于每行一个单词的文件中。如果没有,您必须将所有.
's 更改[^ ]
为匹配非空格字符。(注意:\S
from perl 在许多正则表达式引擎中可用,可能包括您使用的 grep,但与 perl 兼容的正则表达式不是标准的 grep 功能,所以[^ ]
它必须是。)
我不会尝试手动编写这些正则表达式中的任何一个。我为第一个使用了置换生成器,并在 vim 中做了大量的宏录制和重放来编写第二个。
但是让我们看看如果我们反转问题会发生什么。不要尝试匹配包含所有元音的字符串,而是尝试匹配相反的字符串:至少缺少一个元音的字符串。
(从现在开始,我坚持输入中每行一个单词的假设。)
缺少a
匹配项的单词^[^a]*$
(从头到尾,它由除 之外的字符组成a
)。
唯一缺少的一个词e
相匹配^[^e]*$
的是遗漏了一个字i
匹配^[^i]*$
的是遗漏了一个字o
匹配^[^o]*$
的是遗漏了一个字u
匹配^[^u]*$
缺少a
或缺少e
或缺少i
或缺少o
或缺少u
匹配项的单词
^([^a]*|[^e]*|[^i]*|[^o]*|[^u]*)$
Run Code Online (Sandbox Code Playgroud)
所以这个 grep 命令给了你所有你不想要的词:
grep -E '^([^a]*|[^e]*|[^i]*|[^o]*|[^u]*)$' wordlist
Run Code Online (Sandbox Code Playgroud)
和方便的-v
选项给你,你的话也想:
grep -vE '^([^a]*|[^e]*|[^i]*|[^o]*|[^u]*)$' wordlist
Run Code Online (Sandbox Code Playgroud)
-i
如果需要,请添加。
在编写正则表达式时,需要牢记反转技术。有时,一个非常复杂的正则表达式是一个更简单的正则表达式的反面。