【问题标题】:PHP regular expression : match the closest onePHP正则表达式:匹配最接近的一个
【发布时间】:2013-01-09 15:00:54
【问题描述】:

我有一个这样的字符串

<div><span style="">toto</span> some character <span>toto2</span></div>

我的正则表达式:

/(<span .*>)(.*)(<\/span>)/

我使用了 preg_match,它返回整个字符串

<span style="">toto</span> some character <span>toto2</span>

我希望它返回:

<span style="">toto</span>
and
<span>toto2</span>

我需要做什么才能实现这一目标?谢谢。

【问题讨论】:

  • 不要使用正则表达式解析 HTML。您无法使用正则表达式可靠地解析 HTML。一旦 HTML 与您的期望发生变化,您的代码就会被破坏。有关如何使用 PHP 模块正确解析 HTML 的示例,请参阅 htmlparsing.com/php.html
  • @AndyLester 解析器并不是防止 HTML 更改的神奇解决方案。
  • @AndyLester 使用整个解析模块来解析一个简单的 标签似乎有点太重了。我认为任何更改都不会影响这个简单的案例。
  • 比如&lt;span style=""&gt;\ntoto\n&lt;/span&gt;的情况怎么样?如果您正在处理一组不会更改的数据,那么请继续为该特定数据集编写代码。如果您依赖该标记在未来以这样的方式呈现,那么您就是在自找苦恼。

标签: php regex html-parsing


【解决方案1】:

这个怎么样:

/(<span[^>]*>)(.*?)(<\/span>)/

PHP preg_match Repetition查看文档:

默认情况下,量词是“贪婪的”,即尽可能匹配

但是,如果量词后跟问号,则它会变得懒惰,而是匹配可能的最小次数

【讨论】:

  • 虽然我测试过,可以,但是不太明白。为何 ”?”不是在“span”或“>”之后,而是在“.*”之后?
  • 因为您希望.* 匹配尽可能少的字符。
  • 那样的话/&lt;span.*?\&lt;\/span&gt;/就够了?
  • 是的,/&lt;span.*?&lt;\/span&gt;/ 就足够了,如果您不需要在原始表达式中使用 () 创建的组。
  • 对于像这样的简单示例,它可以工作,但我仍然认为如果我们尝试匹配,这会产生意想不到的结果:&lt;span id="aspan"&gt;&lt;span id="child_span"&lt;/span&gt;&lt;/span&gt;
【解决方案2】:

尽管我猜以前所有的答案都是正确的,但我只想补充一点,因为您只想捕获整个表达式(即 from to ),您不必使用 () 捕获正则表达式中的所有内容 以下是您所期望的,无需捕获额外的表达式

/(<span\w*[^>]*>[^<]*<\/span>)/

(在http://rubular.com/ 测试)

编辑:当然,PHP 和 ruby​​ 正则表达式实现之间可能存在一些差异,但想法是相同的 :)

【讨论】:

  • [^、等其他元素
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-22
相关资源
最近更新 更多