【问题标题】:How to match a string not followed by a word using sed如何使用 sed 匹配没有后跟单词的字符串
【发布时间】:2016-07-01 15:32:30
【问题描述】:

我需要删除所有由连字符和空格组成的字符串,但前提是空格后面没有单词“og”。 示例文件:

Kultur- og idrettsavdelinga skapar nyska- pande kunst og utvik- lar samfunnet

我尝试了负前瞻:

sed -e 's/- (?!og)//g'

但它不起作用。我想要的是这样的:

Kultur- og idrettsavdelinga skapar nyskapande kunst og utviklar samfunnet.

有什么想法吗?

【问题讨论】:

  • AFAIK,sed 不支持前瞻和后瞻。source ..您可以改用perl

标签: regex sed


【解决方案1】:

鉴于这个输入文件(我添加了- ellers,因为你在评论中说你也需要处理它们):

$ cat file
Kultur- og idrettsavdelinga skapar- eller nyska- pande kunst og utvik- lar- eller samfunnet

这是常见的 sed 惯用方法:

$ sed 's/a/aA/g; s/- og/aB/g; s/- eller/aC/g; s/- //g; s/aC/- eller/g; s/aB/- og/g; s/aA/a/g' file
Kultur- og idrettsavdelinga skapar- eller nyskapande kunst og utviklar- eller samfunnet

上述方法通过将所有as(或您喜欢的不在目标字符串中的任何其他字符)转换为aA,这样我们就可以转换我们感兴趣的字符串,- og 和@987654327 @,进入a<some other character>,例如aBaC,此时我们知道输入中唯一出现的 aBaC 是新转换的 - og- eller,因为所有现有的as 现在是 aA

现在我们可以从文件中删除所有剩余的-s,然后将aCs 转换回- eller,将aBs 转换回- ogs,最后将所有aAs 转换回原as.

【讨论】:

    【解决方案2】:

    sed 不提供前瞻功能,但您可以描述所有可能性:

    sed -e 's/\(- \(- \)*\)\([^o]\|$\|o\([^g]\|$\)\)/\3/g'
    

    您可以通过以下方式对其进行测试:- - - - og - - oa - o => - og oa o

    【讨论】:

    • 这适用于og(挪威语中的“和”),但他可能还需要寻找eller(“或”)......
    • 你说得对!我也需要寻找“eller”。
    【解决方案3】:

    您也可以使用 sed 链,首先将 - og 替换为无意义的东西(例如 booogabooga),然后执行替换,然后反转 booogabooga

    sed -e 's/- og/booogabooga/g; s/- //g; s/booogabooga/- og/g'
    

    sed 的某些版本可能需要:

    sed -e 's/- og/booogabooga/g' -e 's/- //g' -e 's/booogabooga/- og/g'
    

    这可能会更慢,更痛苦,尤其是当您像@Kusalananda 建议的那样有多个替换时,但它更容易理解。

    【讨论】:

    • 安全、惯用的方法是创建一个输入中不存在的字符串(或多个字符串),而不是尝试猜测一个。见stackoverflow.com/a/38153467/1745001
    • @EdMorton 是的。现在我用 Google 搜索了,有很多 174 results for "booogabooga" 我以为是我编的。
    • 是的,不幸的是,使用 $'\n' 作为临时替换字符串甚至不是 100% 安全,以防有人使用保持空间/缓冲区/时间扭曲巫毒咒语来强制 sed 执行多行操作。
    【解决方案4】:

    这可能对你有用(GNU sed):

    sed -r 's/(- (og|eller))|- /\1/g' file
    

    这依赖于alternation 来重新替换特定情况,以及空的反向引用来替换一般情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-06-02
      • 1970-01-01
      • 2011-09-02
      • 2012-10-18
      • 2019-01-11
      • 1970-01-01
      • 2020-07-11
      • 2016-05-14
      相关资源
      最近更新 更多