【问题标题】:Regex match everything except word正则表达式匹配除单词之外的所有内容
【发布时间】:2019-11-12 05:53:19
【问题描述】:

所有关于匹配除单词以外的内容 的所有 QA 都带有我发现的负前瞻暗示行开始/结束(^$)。但我不知道如何匹配所有内容(任何字符,如.*),除了处理文本中间某个其他单词之前的单词。

我应该在<tag></tag> 中匹配ABC

...<tag>a a.__aABC&*</tag>aaa<tag>ffff</tag>...

但不在外面(误报):

...<tag>a a.__a&*</tag>ABC<tag>ffff</tag>...

所以我认为我应该在ABC 之前排除标签关闭(&lt;/tag&gt;)。 我试过了:

<tag>(?!<\/tag>)ABC.*?<\/tag>

但这种方式不允许ABC 之前匹配&lt;/tag&gt; 之外的.*。我该如何实现?

有用的链接:

1, 2.

【问题讨论】:

  • 这是正则表达式不擅长的两件事:平衡语法和嵌套否定。附带说明一下,最好在您选择的语言中使用 XML 解析器。
  • @Grinnz Сlearly。但毕竟具体描述的问题看起来很简单。正则表达式无法以任何方式解决它?
  • 问题被标记为perl,所以我们可以假设需要Perl 解决方案吗?如果是这样,这种棘手的正则表达式问题就是为什么全宇宙都同意应该使用 XML 解析器来解析 XML。例如,请参阅metacpan.org/pod/XML::LibXML
  • "但毕竟具体描述的问题看起来很简单。" -- 正确。外观可能具有欺骗性,解决了这个问题后还会有另一个问题,因为您正在重新发明一个相当复杂的轮子。
  • @z0lupka 几乎总是可能具有足够功能的正则表达式引擎。但所需的复杂性几乎不值得。如果您指定正在使用的正则表达式引擎,这可能很重要(特别注意 PCRE 不是 Perl)。

标签: regex perl pcre regex-lookarounds regex-negation


【解决方案1】:

由于您使用的是 Perl / PCRE 之一,因此最快的方法是这样的:

/(?s)&lt;tag&gt;(?:&lt;\/tag&gt;(*SKIP)(*FAIL)|.)*?ABC.*?&lt;\/tag&gt;/

https://regex101.com/r/AoiwIH/1

展开

 (?s)
 <tag>  
 (?:
      </tag>
      (*SKIP) (*FAIL) 
   |  
      . 
 )*?
 ABC
 .*? 
 </tag>

断言方法进行基准比较

Regex1:   (?s)<tag>(?:</tag>(*SKIP)(*FAIL)|.)*?ABC.*?</tag>
Completed iterations:   50  /  50     ( x 1000 )
Matches found per iteration:   1
Elapsed Time:    0.25 s,   254.91 ms,   254905 µs
Matches per sec:   196,151


Regex2:   (?s)<tag>(?:(?!</tag>).)*?ABC.*?</tag>
Completed iterations:   50  /  50     ( x 1000 )
Matches found per iteration:   1
Elapsed Time:    0.33 s,   329.10 ms,   329095 µs
Matches per sec:   151,931

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2021-05-26
    • 2022-08-21
    相关资源
    最近更新 更多