【问题标题】:sed-compatible regex matching the middle word of an odd number of wordssed 兼容的正则表达式匹配奇数个单词的中间单词
【发布时间】:2016-07-05 03:04:05
【问题描述】:

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

例如:(输入??????捕获)

  • “苹果”??? “苹果”
  • “零一二”??? “一个”
  • “红蓝绿橙黄”??? “绿色”

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

【问题讨论】:

  • 糟糕,您忘记发布代码了! StackOverflow 旨在帮助人们修复他们的代码。这不是免费的编码服务。任何代码都比没有代码好。元代码甚至可以展示您认为程序应该如何工作,即使您不知道如何编写它。

标签: regex sed


【解决方案1】:

使用 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 是中间字段的数量。

【讨论】:

  • 可能值得指出的是,如果有 even 个字段(以防输入错误),那么(NF+1)/2 将引用这两个字段中的第一个中间字段(所以 awk 向下舍入)。
猜你喜欢
  • 2021-09-21
  • 1970-01-01
  • 1970-01-01
  • 2010-11-15
  • 2012-01-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多