php, strpos 从字符串中提取数字
php, strpos extract digit from string
我有一个巨大的 html 代码要扫描。到目前为止,我一直在使用 preg_match_all
从中提取所需的部分。从一开始的问题就是它非常 cpu 耗时。我们最终决定使用其他方法进行提取。我在一些文章中看到 preg_match
可以与 strpos
在性能上进行比较。他们声称 strpos
在效率上比正则表达式扫描器高出 20 倍。我想我会试试这个方法,但我真的不知道如何开始。
假设我有这个 html 字符串:
<li id="ncc-nba-16451" class="che10"><a href="/en/star">23 - Star</a></li>
<li id="ncd-bbt-5674" class="che10"><a href="/en/moon">54 - Moon</a></li>
<li id="ertw-cxda-c6543" class="che10"><a href="/en/sun">34,780 - Sun</a></li>
我只想从每个 id 中提取数字,并从 a
标签的内容中提取文本(字母)。所以我这样做 preg_match_all
扫描:
'/<li.*?id=".*?([\d]+)".*?<a.*?>.*?([\w]+)<\/a>/s'
在这里你可以看到结果:LINK
现在,如果我想将我的方法替换为 strpos
功能,该方法会是什么样子?我知道 strpos
returns 开始匹配的索引。但我如何使用它来:
- 获取所有可能的匹配项,而不仅仅是一个
- 从字符串中的所需位置提取数字或文本
感谢您提供的所有帮助和提示 ;)
此正则表达式使用 0 个回溯在 24 个步骤中找到匹配项
(?:id="[^\d]*(\d*))[^<]*(?:<a href="[^>]*>[^a-z]*([a-z]*))
您发布的正则表达式需要 134 个步骤。也许你会注意到不同之处?请注意,正则表达式引擎可以进行优化,以便最大限度地减少回溯。我使用 RegexBuddy 的调试器来得出数字。
使用 DOM
$html = '
<html>
<head></head>
<body>
<li id="ncc-nba-16451" class="che10"><a href="/en/star">23 - Star</a></li>
<li id="ncd-bbt-5674" class="che10"><a href="/en/moon">54 - Moon</a></li>
<li id="ertw-cxda-c6543" class="che10"><a href="/en/sun">34,780 - Sun</a></li>
</body>
</html>';
$dom_document = new DOMDocument();
$dom_document->loadHTML($html);
$rootElement = $dom_document->documentElement;
$getId = $rootElement->getElementsByTagName('li');
$res = [];
foreach($getId as $tag)
{
$data = explode('-',$tag->getAttribute('id'));
$res['li_id'][] = end($data);
}
$getNode = $rootElement->getElementsByTagName('a');
foreach($getNode as $tag)
{
$res['a_node'][] = $tag->parentNode->textContent;
}
print_r($res);
输出:
Array
(
[li_id] => Array
(
[0] => 16451
[1] => 5674
[2] => c6543
)
[a_node] => Array
(
[0] => 23 - Star
[1] => 54 - Moon
[2] => 34,780 - Sun
)
)
我有一个巨大的 html 代码要扫描。到目前为止,我一直在使用 preg_match_all
从中提取所需的部分。从一开始的问题就是它非常 cpu 耗时。我们最终决定使用其他方法进行提取。我在一些文章中看到 preg_match
可以与 strpos
在性能上进行比较。他们声称 strpos
在效率上比正则表达式扫描器高出 20 倍。我想我会试试这个方法,但我真的不知道如何开始。
假设我有这个 html 字符串:
<li id="ncc-nba-16451" class="che10"><a href="/en/star">23 - Star</a></li>
<li id="ncd-bbt-5674" class="che10"><a href="/en/moon">54 - Moon</a></li>
<li id="ertw-cxda-c6543" class="che10"><a href="/en/sun">34,780 - Sun</a></li>
我只想从每个 id 中提取数字,并从 a
标签的内容中提取文本(字母)。所以我这样做 preg_match_all
扫描:
'/<li.*?id=".*?([\d]+)".*?<a.*?>.*?([\w]+)<\/a>/s'
在这里你可以看到结果:LINK
现在,如果我想将我的方法替换为 strpos
功能,该方法会是什么样子?我知道 strpos
returns 开始匹配的索引。但我如何使用它来:
- 获取所有可能的匹配项,而不仅仅是一个
- 从字符串中的所需位置提取数字或文本
感谢您提供的所有帮助和提示 ;)
此正则表达式使用 0 个回溯在 24 个步骤中找到匹配项
(?:id="[^\d]*(\d*))[^<]*(?:<a href="[^>]*>[^a-z]*([a-z]*))
您发布的正则表达式需要 134 个步骤。也许你会注意到不同之处?请注意,正则表达式引擎可以进行优化,以便最大限度地减少回溯。我使用 RegexBuddy 的调试器来得出数字。
使用 DOM
$html = '
<html>
<head></head>
<body>
<li id="ncc-nba-16451" class="che10"><a href="/en/star">23 - Star</a></li>
<li id="ncd-bbt-5674" class="che10"><a href="/en/moon">54 - Moon</a></li>
<li id="ertw-cxda-c6543" class="che10"><a href="/en/sun">34,780 - Sun</a></li>
</body>
</html>';
$dom_document = new DOMDocument();
$dom_document->loadHTML($html);
$rootElement = $dom_document->documentElement;
$getId = $rootElement->getElementsByTagName('li');
$res = [];
foreach($getId as $tag)
{
$data = explode('-',$tag->getAttribute('id'));
$res['li_id'][] = end($data);
}
$getNode = $rootElement->getElementsByTagName('a');
foreach($getNode as $tag)
{
$res['a_node'][] = $tag->parentNode->textContent;
}
print_r($res);
输出:
Array
(
[li_id] => Array
(
[0] => 16451
[1] => 5674
[2] => c6543
)
[a_node] => Array
(
[0] => 23 - Star
[1] => 54 - Moon
[2] => 34,780 - Sun
)
)