【问题标题】:PHP regex html data attributes with fixed markup具有固定标记的 PHP 正则表达式 html 数据属性
【发布时间】:2021-04-12 13:55:59
【问题描述】:

我有以下固定模式标记场景

<div class="myclass" id="id123" data-foo="bar">content</div>
<div class="myclass" id="id123" data-foo="bar" >content</div>
<div class="myclass" id="id123" data-foo="bar" data-baz="qux">content</div>
<div class="myclass" id="id123" data-foo="bar" data-baz="qux" >content</div>

我正在尝试解析以下值

id123
bar
qux (if it ever exists)

我能够弄清楚如何获得不同的场景,但我很容易想出一条适用于所有场景的最终规则。

/<div class="myclass" id="(.*)" data-foo="(.*)"(data-baz="(.*)")?>/

我似乎缺少一些基本的正则表达式原则。我尝试了边界和结尾以及空格,但没有运气。

【问题讨论】:

  • 对于任何HTML阅读任务,我更喜欢使用DomDocument,你也可以利用DOMXpath来搜索,基本上regex不是一个简单的HTML解析解决方案。抱歉,我没有为您的挑战提供确切的解决方案/示例。
  • 正确的 Scuzzy。但是,由于性能原因,我故意避开DomDocument
  • 这是个好电话:)

标签: php html regex parsing html-parsing


【解决方案1】:
  1. 我不赞成使用正则表达式来解析 html,但您说您正在优化速度并且标记的结构是可预测的。
  2. 您只需对这些点使用惰性量词,并对可选空格多加注意

代码:(Demo)

$text = <<<TEXT
<div class="myclass" id="id123" data-foo="bar">content</div>
<div class="myclass" id="id123" data-foo="bar" >content</div>
<div class="myclass" id="id123" data-foo="bar" data-baz="qux">content</div>
<div class="myclass" id="id123" data-foo="bar" data-baz="qux" >content</div>
TEXT;

preg_match_all('~<div class="myclass" id="(.*?)" data-foo="(.*?)" ?(?:data-baz="(.*?)" ?)?>~', $text, $matches);
var_export(array_slice($matches, 1));

输出:

  0 => 
  array (
    0 => 'id123',
    1 => 'id123',
    2 => 'id123',
    3 => 'id123',
  ),
  1 => 
  array (
    0 => 'bar',
    1 => 'bar',
    2 => 'bar',
    3 => 'bar',
  ),
  2 => 
  array (
    0 => '',
    1 => '',
    2 => 'qux',
    3 => 'qux',
  ),
)

您可以通过不使用惰性量词来提高正则表达式的效率。如果您知道属性值不会包含双引号,那么您可以使用带有贪心量词的 this 否定字符类:[^"]*

【讨论】:

  • 感谢您的详尽回答和解释。很完美属性值将只包含字母数字和可能的连字符。
猜你喜欢
  • 2019-04-12
  • 2015-03-15
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 2013-06-16
  • 2019-10-09
  • 2010-11-25
相关资源
最近更新 更多