【问题标题】:PHP RegEx Grouping Multiple MatchesPHP RegEx 分组多个匹配项
【发布时间】:2010-11-08 10:23:00
【问题描述】:

我只是在尝试制作我的第一个正则表达式。我希望能够匹配一个伪 HTML 元素并提取有用的信息,例如标签名称、属性等:

$string = '<testtag alpha="value" beta="xyz" gamma="abc"  >';

if (preg_match('/<(\w+?)(\s\w+?\s*=\s*".*?")+\s*>/', $string, $matches)) {
    print_r($matches);
}

除了,我得到:

Array ( [0] =>  [1] => testtag [2] => gamma="abc" ) 

有人知道我如何获得其他属性吗?我错过了什么?

【问题讨论】:

  • 您的第一个正则表达式不应该用于匹配 HTML/XML,因为这是正则表达式真正不擅长的一件事。相信我,它们很糟糕,你应该从一开始就避免使用它们。
  • 但你必须承认这是了解它们的局限性的好方法。 ;)
  • 可能,是的。 ;-) 使用正则表达式很容易培养一种“随心所欲”的态度,让您认为所有以文本表示的内容都是文本。 XML 和 HTML 不是文本,它们是结构化数据,应该使用数据工具而不是文本工具进行处理。提出警告的最佳时间是有人刚开始使用正则表达式时。 :)
  • 感谢所有试图回答我问题的人。看起来不可能按照我想要的方式去做。呸骗子!当你可以使用二十个甚至整个库时,为什么还要使用一行代码?放弃 PHP,.NET 万岁!

标签: php regex


【解决方案1】:

您的第二个捕获组一次匹配一个属性,每次都覆盖前一个。如果您使用的是 .NET 正则表达式,则可以使用 Captures 数组来检索各个捕获,但我不知道任何其他具有该功能的正则表达式风格。通常您必须执行一些操作,例如捕获一组中的所有属性,然后在捕获的文本上使用另一个正则表达式来分解各个属性。

这就是为什么人们倾向于要么喜欢正则表达式要么讨厌它们(或两者兼而有之)。你可以用它们做一些真正令人惊奇的事情,但你也经常遇到像这样的简单任务,即使不是不可能,也很难做到。

【讨论】:

    【解决方案2】:

    如前所述,不要使用 RegEx 来解析 HTML 文档

    试试这个 PHP 解析器:http://simplehtmldom.sourceforge.net/

    【讨论】:

      【解决方案3】:

      试试这个正则表达式:

      /<(\w+)((?:\s+\w+\s*=\s*(?:"[^"]*"|'[^']*'|[^'">\s]*))*)\s*>/
      

      但是对于像 HTML 这样的上下文无关语言,你真的不应该使用正则表达式。请改用真正的解析器。

      【讨论】:

      • 想详细说明我的“真正的解析器”是什么意思?
      • @Tim Lytle:正则表达式不是解析器。它们最多是解析器的一部分。例如,真正的解析器是 XML DOM 解析器——它可以解析语言,而正则表达式只能找到模式。
      • @Tomalak 啊,不明白他的意思。现在很有意义。
      猜你喜欢
      • 2015-08-30
      • 2018-02-14
      • 2015-05-03
      • 2012-05-14
      • 1970-01-01
      • 1970-01-01
      • 2013-01-02
      • 2012-02-22
      • 2014-04-30
      相关资源
      最近更新 更多