匹配通配符而不用 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;
.
条件包含在 [...]
中,并与 or
或 and
连接。它们也可以用圆括号分组。您还可以使用 not(...)
来反转条件。 XPath 在这种情况下非常有用。
我正在尝试从如下所示的元素中捕获 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;
.
条件包含在 [...]
中,并与 or
或 and
连接。它们也可以用圆括号分组。您还可以使用 not(...)
来反转条件。 XPath 在这种情况下非常有用。