sed兼容的正则表达式匹配奇数个单词的中间词

时间:2016-07-05 03:04:06

标签: regex sed

如果单词的数量总是奇数,那么如何使用正则表达式来捕获奇数个空格分隔的单词的中间单词?任何sed兼容的正则表达式都可以,包括扩展(sed -r)。

例如:(输入捕获)

  • "苹果" "苹果"
  • "零一两" "一个"
  • "红蓝绿橙黄" "绿色"

我怀疑如果没有更强大的正则表达式库(例如PCRE)提供的某些扩展,这可能是不可能的。我相信在正则表达式的经典正式语言定义下它是不可能的。
如果sed无法做到这一点,那么如何使用不同的正则表达式引擎的功能来完成同样的事情呢?

1 个答案:

答案 0 :(得分:3)

使用sed

$ sed -E ':a; s/^[^ ]+ //; s/ [^ ]+$//; ta;' file
apple
one
green

以上假设为GNU sed。对于BSD(OSX)sed,需要进行一些小修改。

如何运作

  • :a

    这定义了标签a

  • s/^[^ ]+ //; s/ [^ ]+$//

    这些替换命令中的第一个从行的开头删除一个单词和一个空格。第二个从末尾删除一个空格和单词。

    这样可以删除该行的两端,直到只剩下一个单词。

  • ta

    如果上述替换命令确实导致替换,则转移到标签a

    当该行只剩下一个单词时,则替换不执行任何操作,并且分支停止。

使用awk

使用awk,我们可以直接访问中间词:

$ awk '{print $((NF+1)/2)}' file
apple
one
green

在awk中,NF是字段数。如果根据此问题存在奇数个字段,则(NF+1)/2是中间字段的编号。