【问题标题】:Negative Lookahead in RegExp not working as expectedRegExp 中的负前瞻未按预期工作
【发布时间】:2020-09-23 15:49:10
【问题描述】:

我想写两个正则表达式:第一个匹配以不是 或 的标记开头的字符串。然后是第二个匹配以不是 或 的标记结尾的字符串。

字符串 CH5 应该匹配两个 RegExp。

字符串 Something 不应匹配两个 RegExp 中的任何一个。

我认为negative lookahead 可能值得一试,但不知何故并没有按预期工作。

对于“以非 sub/sup-tag 开头”,我使用了以下内容:^.+

对于“以非 sub/sup-tag 结尾”,我使用了以下内容:.+(?!su[bp])>

两者都不起作用。我做错了什么?

【问题讨论】:

    标签: regex regex-lookarounds


    【解决方案1】:

    您的模式不匹配,因为断言 (?!su[bp]) 始终为真,因为模式匹配的下一件事是 >。

    所以第一个将匹配例如<>a,第二个将匹配例如a</>


    * 例如,假设字符<和>不能出现在关闭>之前

    如果您想要 2 个模式,则在第一个模式中,您可以先匹配到结束 >,然后再匹配该行的其余部分。

    ^<(?!su[bp]\b)[^<>]+>.+
    
    • ^ 字符串开始
    • &lt; 字面匹配
    • (?!su[bp]\b) 负前瞻,断言直接向右的不是 sub 或 sup
    • [^&lt;&gt;]+&gt; 匹配除 &lt; 和 &gt; 以外的任何字符的 1+ 次
    • .+ 匹配任意字符 1+ 次

    Regex demo

    在第二个模式中你可以这样做,但你必须匹配结束 &gt; 之前的内容,因为前瞻是不消耗的。

    .+</(?!su[bp]\b)[^<>]+>$
    
    • .+ 匹配任意字符 1+ 次
    • &lt;/ 字面匹配
    • (?!su[bp]\b&gt;) 负前瞻,断言直接向右的不是 sub 或 sup
    • [^&lt;&gt;]+ 匹配除 &lt; 和 &gt; 以外的任何字符的 1 次以上
    • $ 字符串结束。

    Regex demo

    备注

    • 使用.+ 是一个非常广泛的匹配,点将匹配任何字符。
    • 如果您正在处理 html 或 xml 之类的结构化数据,我建议您改用解析器。

    【讨论】:

    • 非常感谢您的解释。两者都运作良好。与在 Java 中使用它时一样:不要忘记转义反斜杠 :-)
    【解决方案2】:

    考虑关于位置的前瞻。

    在^&lt;(?!su[bp])&gt;.+ 中,您告诉引擎匹配此序列:

    • 行首
    • 一个&lt;
    • &lt; 后面的位置不能跟 sub 或 sup
    • 一个&gt;
    • 多个字符之一

    第三个条件是你想错了。

    你想要的正则表达式是:

    ^<(?!sub[bp]).+?>.+
    

    所以您告诉引擎在&lt; 和&gt;(由.+? 给出)之间匹配尽可能少的字符,但&lt; 后面不应跟sub 或sup

    【讨论】:

    • 感谢您的回答,但 RegExp 也匹配 Something。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多