【问题标题】:regex idiom for excluding word while matching other conditions用于在匹配其他条件时排除单词的正则表达式习语
【发布时间】:2014-07-31 21:49:46
【问题描述】:

问题如下。我需要匹配每一行:

  • <开头
  • 内部没有标签<s>
  • 以标签</s>结尾

例子:

<div> blablabla </div> blablabla </s>
<div> blablabla </div> <s> blablabla </s>

我一直在尝试放置一个否定的前瞻和一个通配符

^<((?!<s>).)*</s>$

也考虑过this trick,但目前没有成功。我也知道

grep -v

但我想要一个纯正则表达式习语,然后我可以在其他上下文中使用(如 sed)

【问题讨论】:

    标签: regex sed grep negative-lookahead


    【解决方案1】:

    您可以使用以下正则表达式:

    ^(?!.*<s>)<.*</s>$
    

    说明

    ^          # the beginning of the string
    (?!        # look ahead to see if there is not:
      .*       #   any character except \n (0 or more times)
      <s>      #   '<s>'
    )          # end of look-ahead
    <          # '<'
    .*         # any character except \n (0 or more times)
    </s>       # '</s>'
    $          # before an optional \n, and the end of the string
    

    Live Demo

    使用 grep,您可以使用 -P 选项,它将模式解释为 Perl 正则表达式。

    grep -P '^(?!.*<s>)<.*</s>$'
    

    您也可以考虑在上下文中使用交替运算符,将您想要排除的内容放在左侧(说扔掉它,这是垃圾)并将您想要匹配的内容放在捕获组中在右侧。

    ^.*<s>.*|(<.*</s>)$
    

    Live Demo

    【讨论】:

      【解决方案2】:

      您提到了grep -v 方法,但想要一个“我可以在其他上下文中使用的习语(例如 sed)”。实际上,grep -v 方法也适用于sed。它还通过避免所有花哨的(通常不受支持的)正则表达式结构来保持它非常简单。实现如下:

      sed -n '/<s>/n; /^<.*<\/s>/p' file
      

      一次检查一件:

      • -n

        这告诉sed 除非明确要求,否则不要打印任何内容。

      • /&lt;s&gt;/n;

        这告诉sed 跳过任何带有&lt;s&gt; 的行。该命令类似于grep -v。 (在sed 中,n 命令表示跳到下一行。)

      • /^&lt;.*&lt;\/s&gt;/p

        这会选择你想要的行并打印出来。

      Mac OSX 笔记

      如果我没记错的话,OSX sed(可能还有其他非 GNU seds)不支持与分号组合的命令。解决方法是使用-e:

      sed -n -e '/<s>/n' -e '/^<.*<\/s>/p' file
      

      【讨论】:

        【解决方案3】:

        你几乎得到了答案。

        ^(?!.*<s>)<.*?</s>
        

        您当前的模式所做的是搜索以&lt; 开头的字符串,但不是紧跟&lt;s&gt;。而&lt;s&gt; 标签可以出现在您的文本中的任何位置。

        【讨论】:

          【解决方案4】:

          使用您评论的技巧可以帮助您。

          如果你使用这个正则表达式:

          .*<s>.*|(.*<\/s>)
          

          您将在捕获组中拥有所需的行。

          你有一个working example

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-09-10
            • 1970-01-01
            • 1970-01-01
            • 2016-12-06
            • 2020-11-22
            • 1970-01-01
            • 2021-10-11
            • 2016-05-06
            相关资源
            最近更新 更多