如何在 PHP 中捕获带有可选空格的链接?
How to catch links with optional spaces in PHP?
从 file_get_contents
我得到 url 的 HTML 代码。
$html = file_get_contents($url);
现在我要捕获 href
link.
HTML代码是:
<li class="four-column mosaicElement">
<a href="https://example.com" title="Lorem ipsum">
...
</a>
</li>
<li class="four-column mosaicElement">
<a href="https://example.org" title="Lorem ipsum">
...
</a>
</li>
所以我正在使用这个:
preg_match_all('/class=\"four-column mosaicElement\"><a href=\"(.+?)\" title=\"(.+?)"/m', $html, $urls, PREG_SET_ORDER, 0);
foreach ($urls as $key => $url) {
echo $url[1];
}
如何解决这个问题?
我只需将正则表达式模式修改为以下内容,就能让您的代码正常工作:
class="four-column mosaicElement">\s*<a href="(.+?)" title="(.+?)"
^^^^^
请注意,我允许在外部标记 (<li>
) 的 class
属性和内部锚点之间有任意数量的空格。
这是您更新后的脚本:
$html = "<li class=\"four-column mosaicElement\">\n<a href=\"https://example.com\" title=\"Lorem ipsum\">\n</a>\n</li>\n<li class=\"four-column mosaicElement\">\n<a href=\"https://example.org\" title=\"Lorem ipsum\">\n</a>\n</li>";
preg_match_all('/class="four-column mosaicElement">\s*<a href="(.+?)" title="(.+?)"/m', $html, $urls, PREG_SET_ORDER, 0);
foreach ($urls as $key => $url) {
echo $url[1] . "\n";
}
这会打印:
https://example.com
https://example.org
另一种选择是将 DOMXPath 与 xpath 表达式一起使用,该表达式查找具有两个 class 名称的所有列表项,然后获取锚点:
//li[contains(@class, 'four-column') and contains(@class, 'mosaicElement')]/a
例如:
$string = <<<DATA
<li class="four-column mosaicElement">
<a href="https://example.com" title="Lorem ipsum">
</a>
</li>
<li class="four-column mosaicElement">
<a href="https://example.org" title="Lorem ipsum">
</a>
</li>
DATA;
$dom = new DOMDocument();
$dom->loadHTML($string);
$xpath = new DOMXpath($dom);
foreach($xpath->query("//li[contains(@class, 'four-column') and contains(@class, 'mosaicElement')]/a") as $v) {
echo $v->getAttribute("href") . PHP_EOL;
}
结果
https://example.com
https://example.org
看到一个php demo
这里,我们也可以使用正向前瞻和可选空格的表达式,以防万一,
(?=class="four-column mosaicElement")[\s\S]*?href="\s*(https?[^\s]+)\s*"
我们想要的网址在这个组中:
(https?[^\s]+)
DEMO
测试
$re = '/(?=class="four-column mosaicElement")[\s\S]*?href="\s*(https?[^\s]+)\s*"/m';
$str = '<li class="four-column mosaicElement">
<a href="https://example.com" title="Lorem ipsum">
...
</a>
</li>
<li class="four-column mosaicElement">
<a href="https://example.org" title="Lorem ipsum">
<li class="four-column mosaicElement">
<a href=" https://example.org " title="Lorem ipsum">
<li class="four-column mosaicElement">
<a href=" https://example.org " title="Lorem ipsum">
...
</a>
</li>
';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
foreach ($matches as $key => $url) {
echo $url[1] . "\n";
}
输出
https://example.com
https://example.org
https://example.org
https://example.org
正则表达式电路
jex.im 可视化正则表达式:
从 file_get_contents
我得到 url 的 HTML 代码。
$html = file_get_contents($url);
现在我要捕获 href
link.
HTML代码是:
<li class="four-column mosaicElement">
<a href="https://example.com" title="Lorem ipsum">
...
</a>
</li>
<li class="four-column mosaicElement">
<a href="https://example.org" title="Lorem ipsum">
...
</a>
</li>
所以我正在使用这个:
preg_match_all('/class=\"four-column mosaicElement\"><a href=\"(.+?)\" title=\"(.+?)"/m', $html, $urls, PREG_SET_ORDER, 0);
foreach ($urls as $key => $url) {
echo $url[1];
}
如何解决这个问题?
我只需将正则表达式模式修改为以下内容,就能让您的代码正常工作:
class="four-column mosaicElement">\s*<a href="(.+?)" title="(.+?)"
^^^^^
请注意,我允许在外部标记 (<li>
) 的 class
属性和内部锚点之间有任意数量的空格。
这是您更新后的脚本:
$html = "<li class=\"four-column mosaicElement\">\n<a href=\"https://example.com\" title=\"Lorem ipsum\">\n</a>\n</li>\n<li class=\"four-column mosaicElement\">\n<a href=\"https://example.org\" title=\"Lorem ipsum\">\n</a>\n</li>";
preg_match_all('/class="four-column mosaicElement">\s*<a href="(.+?)" title="(.+?)"/m', $html, $urls, PREG_SET_ORDER, 0);
foreach ($urls as $key => $url) {
echo $url[1] . "\n";
}
这会打印:
https://example.com
https://example.org
另一种选择是将 DOMXPath 与 xpath 表达式一起使用,该表达式查找具有两个 class 名称的所有列表项,然后获取锚点:
//li[contains(@class, 'four-column') and contains(@class, 'mosaicElement')]/a
例如:
$string = <<<DATA
<li class="four-column mosaicElement">
<a href="https://example.com" title="Lorem ipsum">
</a>
</li>
<li class="four-column mosaicElement">
<a href="https://example.org" title="Lorem ipsum">
</a>
</li>
DATA;
$dom = new DOMDocument();
$dom->loadHTML($string);
$xpath = new DOMXpath($dom);
foreach($xpath->query("//li[contains(@class, 'four-column') and contains(@class, 'mosaicElement')]/a") as $v) {
echo $v->getAttribute("href") . PHP_EOL;
}
结果
https://example.com
https://example.org
看到一个php demo
这里,我们也可以使用正向前瞻和可选空格的表达式,以防万一,
(?=class="four-column mosaicElement")[\s\S]*?href="\s*(https?[^\s]+)\s*"
我们想要的网址在这个组中:
(https?[^\s]+)
DEMO
测试
$re = '/(?=class="four-column mosaicElement")[\s\S]*?href="\s*(https?[^\s]+)\s*"/m';
$str = '<li class="four-column mosaicElement">
<a href="https://example.com" title="Lorem ipsum">
...
</a>
</li>
<li class="four-column mosaicElement">
<a href="https://example.org" title="Lorem ipsum">
<li class="four-column mosaicElement">
<a href=" https://example.org " title="Lorem ipsum">
<li class="four-column mosaicElement">
<a href=" https://example.org " title="Lorem ipsum">
...
</a>
</li>
';
preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
foreach ($matches as $key => $url) {
echo $url[1] . "\n";
}
输出
https://example.com
https://example.org
https://example.org
https://example.org
正则表达式电路
jex.im 可视化正则表达式: