匹配特定长度的单词,锚定,不做魔术数学

时间:2014-08-08 19:40:12

标签: regex grep

我想说我想在/usr/share/dict/words中找到以c开头并以er结尾的所有12个字母的单词。在我的头顶,一个可行的模式可能看起来像:

grep -E '^c.{9}er$' /usr/share/dict/words

它找到了:

cabinetmaker
calcographer
calligrapher
campanologer
campylometer
...

.{9}困扰我。感觉太魔法,从原始约束中定义的数字中减去所有锚点字符的总长度。

有没有办法重写这个正则表达式,所以它不需要预先进行这个计算,允许在模式中直接使用文字12

4 个答案:

答案 0 :(得分:2)

您可以使用-x选项,该选项仅选择与整行完全匹配的匹配。

grep -xE '.{12}' | grep 'c.*er'

Ideone Demo

或使用-P选项将模式阐明为Perl正则表达式并使用前瞻断言。

grep -P '^(?=.{12}$)c.*er$'

Ideone Demo

答案 1 :(得分:0)

您可以使用awk作为替代方案并避免此计算:

awk -v len=12 'length($1)==len && $1 ~ /^c.*?er$/' file

答案 2 :(得分:0)

我不太了解grep,但是一些更高级的NFA RegEx实现为您提供了前瞻和后瞻。如果你能找到任何方法让你可以使用它们,你可以写:

^(?=c).{12}(?<=er)$

也许像这样的perl单行?

cat /usr/share/dict/words | perl -ne "print if m/^(?=c).{12}(?<=er)$/"

答案 3 :(得分:0)

使用GNU sed的一种方法:

$ sed -nr '/^.{12}$/{/^c.*er$/p}' words

使用BSD sed (Mac OS),它将是:

$ sed -nE '/^.{12}$/{/^c.*er$/p;}' words