【问题标题】:Regex to match multiline string start with x, ends with y and contains z but not x in the middle正则表达式匹配多行字符串以 x 开头,以 y 结尾并包含 z 但中间不包含 x
【发布时间】:2014-07-10 09:13:33
【问题描述】:

最好用一个例子来解释。

这是文本:

<li>hello 
THE WORDS
</li>

<li> cruel </li>

<li> world THE WORDS </li>

我想查找以&lt;li&gt; 开头并以&lt;/li&gt; 结尾并包含THE WORDS 的字符串。我希望只匹配&lt;li&gt; hello THE WORDS &lt;/li&gt;&lt;li&gt; world THE WORDS &lt;/li&gt;

我尝试了什么:(?s)&lt;li&gt;.*?(THE WORDS).*?&lt;/li&gt;

这样,第二个匹配是&lt;li&gt; cruel &lt;/li&gt; &lt;li&gt; world THE WORDS &lt;/li&gt;

我正在使用 Sublime Text。

【问题讨论】:

  • 我相信你的“例子”比实际数据更难。换行符是否总是在您的示例中的位置?字符串“xx”和“yy”可以出现在行内吗?
  • @RoToRa 我更新了我的示例。换行符可以在除“THE WORDS”和“
  • ”部分之外的任何地方,文本中没有“
  • ”。
  • 啊,那里的情况非常、非常、非常不同。首先要说的是:您不应该在 HTML 中使用正则表达式。为什么你必须在这里使用 Sublime?考虑到这是 HTML,浏览器中的 JavaScript 会是更好的选择。
  • 标签: regex sublimetext non-greedy


    【解决方案1】:

    编辑:对于新要求,请使用此正则表达式:

    (?s)<li>(?:(?!</li>).)*?THE WORDS.*?</li>
    

    说明

    • (?s) 激活 DOTALL 模式,允许点跨行匹配
    • &lt;li&gt; 匹配文字字符
    • (?:(?!&lt;/li&gt;).) 断言后面的不是&lt;/li 并且匹配一个字符
    • *? 量词让我们懒惰地匹配到......
    • THE WORDS
      • *? 量词让我们懒惰地匹配到......
    • 文字&lt;/li&gt;

    原始答案(不同要求):

    使用这个简单的正则表达式(在 Sublime 中测试):

    x+[^xy]*z[^xy]*y+
    

    regex demo 中查看匹配项。

    说明

    • x+ 匹配一个或多个 x 字符
    • [^xy]* 匹配既不是x 也不是y 的任何字符
    • z 匹配我们想要的 z(确保至少有一个)
    • [^xy]* 匹配既不是x 也不是y 的任何字符
    • y+ 匹配一个或多个 y 字符

    【讨论】:

    • 仅供参考:添加了演示和解释。 :)
    • 很棒 :) 例子和解释
    • 没问题,更新了答案:(?s)&lt;li&gt;(?:(?!&lt;/li).)*?THE WORDS.*?&lt;/li&gt; 将添加解释,让我知道这是否适合您。 :)
    • 谢谢,很高兴它有帮助。 :)
    【解决方案2】:

    以下命令将仅匹配xx hello zz yyxx world zz yy 字符串,并仅从这两个字符串中捕获zz

    <li>(?:(?!<\/li>).)*(THE WORDS).*?<\/li>
    

    DEMO

    【讨论】:

    • 我的文字只是示例,一个块中可能有更多行。有了这个逻辑,我需要把每个案例都写成一个 or 语句。
    • @m_poorUser 这个regex101.com/r/bY3lL5/4 怎么样?如果中间有任意数量的行,它应该可以工作
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签