【问题标题】:Regex that starts and ends with specific string, and does not have (other) string in the middle以特定字符串开头和结尾的正则表达式,中间没有(其他)字符串
【发布时间】:2015-09-23 01:15:22
【问题描述】:

我正在尝试匹配 html 文档中以特定字符串开头和结尾的字符串,并且中间没有另一个特定字符串。更具体地说,它们以

开头
$start = "<br/>\s*[0-9]{1,4}(\.|\:|\))+";

结尾
$end = "\?";

并且应该包含所有内容,但中间的断线。

目前我的中间正则表达式如下所示:

$middle = "[^(<br/>)]+";

最终代码将如下所示:

$start = "<br/>\s*[0-9]{1,4}(\.|\:|\))+";
$middle = //What do I put here?
$end = "\?";
$regex = "#".$start.$middle.$end."#";
preg_match_all($regex, $text, $hits);

我应该如何创建我的中间正则表达式以仅匹配不包含断线的文本?

【问题讨论】:

  • 至少双转义反斜杠。 $middle 不应该有锚点——因为它在中间。而如果是HTML解析,使用DOMDocument。请发布您正在使用的 HTML 示例,并告诉我们您想用它做什么。

标签: php regex string


【解决方案1】:

如果你使用an expression like this,你应该会得到你期望的结果(虽然,有better ways to parse HTML):

(?:(?!<br/>).)*

这本质上是.* 的类固醇。 (?:...) 是一个“非捕获”组,用于将所有内容组合在一起以进行 * 重复。 (?!...) 是一个负前瞻,这意味着它确保在当前位置之前没有找到 &lt;br/&gt;。所以,这个表达式确保没有 &lt;br/&gt; 然后匹配下一个字符,然后重复!


在你的表达中,[^(&lt;br/&gt;)]+,你误解了字符类的工作原理。也就是说,只要它不在以下字符集中,匹配任何字符 1 次以上:(br/&gt;)。也许this demo 会解释得更好。

【讨论】:

  • 很好的答案解决了我的问题,感谢您解释为什么我的表达不起作用。
【解决方案2】:

如果您要匹配 &lt;br /&gt;? 之间的任何 html 文本:

  • 不包含任何其他&lt;br /&gt;,则此表达式有效:

    &lt;br\s?\/&gt;\s*([0-9]{1,4})[.:)]((?:(?!&lt;br\s?\/&gt;).)*)\?

Take a look at this demo

  • 可能包含 &lt;br /&gt; 但您只对删除了 &lt;br /&gt; 的文本感兴趣,那么您可能应该匹配 &lt;br /&gt;? 之间的所有内容,如下所示:

    &lt;br\s?\/&gt;\s*([0-9]{1,4})[.:)]([^?]*)\?

并使用字符串替换或其他方式删除&lt;br /&gt;Take a look at this demo

在每种情况下,第一组将匹配您的要点编号,第二组将匹配要点后面的问题,假设这是您感兴趣的内容。上面的表达式允许不一致的标签,例如&lt;br&gt; , &lt;br &gt;&lt;br/&gt;&lt;br /&gt;

【讨论】:

  • 也是一个很好的答案,与所选答案非常相似。您设法弄清楚了我要从 html 中提取的内容,为此提供了道具。演示也非常棒,非常感谢。
猜你喜欢
  • 2017-09-17
  • 2013-08-04
  • 2023-01-02
  • 1970-01-01
  • 1970-01-01
  • 2016-12-07
  • 1970-01-01
  • 2017-09-12
  • 2019-08-26
相关资源
最近更新 更多