【问题标题】:Regex match a string that doesn't contains a string正则表达式匹配不包含字符串的字符串
【发布时间】:2016-04-21 08:50:34
【问题描述】:

我想用<span> 替换html 中的所有<span...>(包括<span id="...<span class="...),除非跨度以<span id="textmarker 开头(例如,我不想保留这个跨度:<span attr="blah" id="textmarker">)

我已经尝试了herehere 提出的正则表达式,我终于想出了这个永远不会返回<span id="textmarker 的正则表达式,但不知何故它有时会错过其他跨度:

<span(?!.*? id="textmarker).*?">

您可以在此处查看我的(简化的)html:https://regex101.com/r/yT9jG2/2

奇怪的是,如果我在 notepad++ 中运行正则表达式,它会返回 3 个匹配项(第二段中的三个跨度),但 regex101 只返回 1 个匹配项。 Notepad++ 和 regex101 都错过了第一段的跨度。

这个正则表达式也不会返回它应该返回的每个跨度(参见带有灰色突出显示的跨度here

<span(?![^>]*? id="textmarker)[^>]*?>

【问题讨论】:

  • 错误 #1:使用正则表达式来操作 html。你应该使用 DOM 解析器。
  • 您只想排除以id=... 开头的spans,还是要排除spans,其中id=... 不是第一个属性?
  • @Brendan,我已经编辑了问题
  • &lt;span attr="blah" id="textmarker"&gt; 呢?
  • @BrendanAbel 感谢您帮助我更精确,请参阅问题中的编辑。

标签: html regex


【解决方案1】:

更新:排除id="textmarker,同时包括id="anythingelse和所有其他spans:

(<span(?! *id="textmarker)[^>]*>)

在您发布的示例中:https://regex101.com/r/yT9jG2/2,并在顶部选择version 2,将字段设置为:

  • 字段 1:(&lt;span(?! *id="textmarker)[^&gt;]*&gt;)
  • 字段 2,(允许您设置修饰符的较小字段):g

以您的示例并选择version 2,匹配9并在右侧列出它们,包括空跨度以及非id="textmarker,例如&lt;span id="YellowType"&gt;

说明

字段 1:

  • 可选:()。出于教育目的,在表达式中添加了一个额外的外括号,仅用于使用 regex101 的匹配组列表功能在右侧窗格中列出结果,以及默认的内联匹配突出显示。当使用Notepad++ 时,您当然可以省略这些外部( ) 括号。
  • &lt;span:匹配&lt;span
  • (?! 为以下内容启动否定前瞻断言,
  • * 表示空格零次或多次,以防您有多余的空格
  • 后跟id="textmarker
  • ) 结束否定的前瞻断言
  • 因此,如果匹配项看到否定的前瞻断言,它会自动将其作为匹配项丢弃
  • [^ 启动排除集。所以not of of the following,下面是&gt;
  • ] 停止定义排除项
  • * 匹配前面 0 次或更多次。前面是[^&gt;]
  • &gt; 匹配到 open-a-span 标签的结尾

字段 2

  • g 告诉 regex101 你希望这是一个贪婪匹配
  • 所以结果不会在第一次匹配时停止,而是会包含所有匹配项

【讨论】:

  • 不错的尝试,但不幸的是,正则表达式也应该匹配所有其他span id而不是&lt;span id="textmarker"(示例是简化版本,我会更新它!)
  • 这会检测到i,因此它应该可以排除任何跨度 ID,是的,如果不工作,请使用更多信息更新问题
  • 在阅读您的解释之前,我宁愿使用\s 而不是空间和“教育目的”混淆:) 广泛的答案。
猜你喜欢
  • 1970-01-01
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-02
  • 2021-11-13
  • 1970-01-01
  • 2022-11-22
相关资源
最近更新 更多