匹配通配符而不用 preg_match_all 添加到数组

Matching wildcard without adding to the array with preg_match_all

我正在尝试从如下所示的元素中捕获 table 文本:

<span id="ctl00_MainContent_ListView2_ctrl2_ctl01_Label17" class="vehicledetailTable" style="display:inline-block;width:475px;">OWNED</span><br />                                            

我的preg_match_all看起来像:

preg_match_all('~475px;">(.*?)</span><br />~', $ret, $vehicle);

问题是页面上还有其他 table 也匹配,但数据与我的查询不相关。我想要的数据都在“ListView2”中,但“ct101_Label17”有所不同 - Label18、Label19、Label20 等.

由于我对捕获标签不感兴趣,有没有一种方法可以在不捕获匹配的情况下匹配主题字符串?大致如下:

<span id="ctl00_MainContent_ListView2_ctrl2_ctl01_[**WILDCARD HERE**]" class="vehicledetailTable" style="display:inline-block;width:475px;">OWNED</span><br />    

如有任何帮助,我们将不胜感激。

这是您目前正在考虑的一个非常糟糕的解决方案:

<span\b[^<>]*\bid="ctl00_MainContent_ListView2_ctrl2_ctl01_[^"]*"[^<>]*475px;">(.*?)</span><br\s*/>

demo

它确保我们找到了一个 <span> 标签并且有 id 属性以 ctl00_MainContent_ListView2_ctrl2_ctl01_ 开头,还有一些属性(你知道它是 style ) 以 475px; 结尾,然后我们只捕获结束 </span> 标记之前的任何内容。

您可以使用 DOM 和 XPath 来实现,这是一个更安全的解决方案,使用与上述相同的逻辑:

$html = "<span id=\"ctl00_MainContent_ListView2_ctrl2_ctl01_Label17\" class=\"vehicledetailTable\" style=\"display:inline-block;width:475px;\">OWNED</span><br />"; 
$dom = new DomDocument();
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$spans = $xpath->query("//span[starts-with(@id,'ctl00_MainContent_ListView2_ctrl2_ctl01_') and @class='vehicledetailTable'  and contains(@style,'475px;')]");
$data = array();
foreach ($spans as $span) {
    array_push($data, $span->textContent);
}
print_r($data);

输出:[0] => OWNED

注意XPath表达式包含3个条件,随意修改:

  • //span - 获取所有
  • 的跨度标签
  • starts-with(@id,'ctl00_MainContent_ListView2_ctrl2_ctl01_') - 属性 id 的值以 ctl00_MainContent_ListView2_ctrl2_ctl01_
  • 开头
  • @class='vehicledetailTable' - 并且 class 属性的值等于 vehicledetailTable
  • contains(@style,'475px;') - 并且有一个 style 属性,其值包含 475px;.

条件包含在 [...] 中,并与 orand 连接。它们也可以用圆括号分组。您还可以使用 not(...) 来反转条件。 XPath 在这种情况下非常有用。