如何使用grep命令搜索不包含连续辅音的单词?

如何使用grep命令搜索不包含连续辅音的单词?

grep -Ev '[^aeiouy]{2}'应该给出答案(假设输入的每行只有一个由 ASCII 小写字母组成的单词)。

但是,有没有办法做到这一点-v

答案1

对于正匹配,您需要确保如果有辅音,它们后面或前面都没有辅音,每个辅音前面都是行首或元音,后面是行尾或一个元音。

所以:

v='[aeiouy]' c='[^aeiouy]'
grep -xE "($c?$v)*$c?"
$ grep -cxE "($c?$v)*$c?" /usr/share/dict/words
11353
$ grep -cvE "$c$c" /usr/share/dict/words
11353
$ diff -s <(grep -xE "($c?$v)*$c?" /usr/share/dict/words) <(grep -vE "$c{2}" /usr/share/dict/words)
Files /proc/self/fd/11 and /proc/self/fd/18 are identical

答案2

使用(以前称为 Perl_6)

raku -ne '.put unless m:i/ <-[aeiouy]> ** 2 /;'

#OR

raku -ne '.put unless m:i/ <[bcdfghjklmnpqrstvwxz]> ** 2 /;'

如果 OP 遇到已发布的grep解决方案无法处理的 Unicode,则另一种选择。根据最近的 MacOS (BSD?) grep 手册页:“grep 实用程序不会标准化 Unicode 输入,因此包含组合字符的模式将与分解的输入不匹配,反之亦然。”(据报道,Raku 可以标准化 Unicode 输入:请参阅下面的 URL)。

比较上面两种不同的解决方案。请注意,必须使用:i不区分大小写的匹配才能获得相同的结果:

~$ raku -ne 'state $i; ++$i unless m:i/ <-[aeiouy]> ** 2 /; END $i.say;' /usr/share/dict/words
38048
~$ raku -ne 'state $i; ++$i unless m:i/ <[bcdfghjklmnpqrstvwxz]> ** 2 /; END $i.say;' /usr/share/dict/words
38048
~$ diff -s <(raku -ne '.put unless m:i/ <-[aeiouy]> ** 2 /;' /usr/share/dict/words) <(raku -ne '.put unless m:i/ <[bcdfghjklmnpqrstvwxz]> ** 2 /;' /usr/share/dict/words)
Files /dev/fd/63 and /dev/fd/62 are identical

https://docs.raku.org/language/unicode
https://raku.org

相关内容