PHP preg_match_all正在努力解决相同代码的多个实例

时间:2017-11-23 18:02:41

标签: php html regex preg-match-all

我正在以这种格式处理批量数据:

cat /dev/input/event1

我正在提取图像路径。

这是我的正则表达式:

<div class="game"><img src="image.jpg"></div>

这是我的preg_match_all命令:

\<div class\=\"game\"\>\<img src\=\"(.*)\"\>\<\/div\>

如果我尝试处理单个div / img标签,它会起作用,如下所示:

preg_match_all("/\<div class\=\\"game\\"\>\<img src\=\\"(.*)\\"\>\<\/div\>/", $input_lines, $output_array);

但是,当我处理批量数据时,它会失败,例如处理时:

array(2
0   =>  array(1
0   =>  <div class="game"><img src="image.jpg"></div>
)
1   =>  array(1
0   =>  image.jpg
)
)

返回的数组是:

<div class="game"><img src="image.jpg"></div><div class="game"><img src="image2.jpg"></div><div class="game"><img src="image3.jpg"></div><div class="game"><img src="image4.jpg"></div>

它匹配第一个

之间的所有内容
array(2
0   =>  array(1
0   =>  <div class="game"><img src="image.jpg"></div><div class="game">
<img src="image2.jpg"></div><div class="game"><img src="image3.jpg">
</div><div class="game"><img src="image4.jpg"></div>
)
1   =>  array(1
0   =>  image.jpg"></div><div class="game"><img src="image2.jpg"></div>
<div class="game"><img src="image3.jpg"></div><div class="game"><img 
src="image4.jpg
)
)

和最后一次

<div class="game"><img src="

我有点理解为什么会这样,但必须有办法防止这种情况发生?我打赌它很简单,我尝试了很多东西,并且谷歌搜索了各种各样的东西......很难列出所有东西。

2 个答案:

答案 0 :(得分:1)

正如评论中所述,只需将.*更改为.*?即可解决您的问题。此答案是该解决方案的替代方案,该方案在完全匹配而不是捕获组中返回图像源。与.*?选项相比,此解决方案还使用更少的步骤来达到预期结果,并且还考虑了空白的可能性。

此外,作为旁注,您不需要在正则表达式中转义每个字符,只有\/[]()?*+.^$

等特殊字符

代码

See regex in use here

<div\s+class="game"\s*>\s*<img\s+src="\K[^"]*(?="\s*>\s*</div>)

结果

输入

<div class="game"><img src="image.jpg"></div><div class="game">
<img src="image2.jpg"></div><div class="game"><img src="image3.jpg">
</div><div class="game"><img src="image4.jpg"></div>

输出

image.jpg
image2.jpg
image2.jpg
image4.jpg

说明

  • <div按字面意思匹配
  • \s+匹配一个或多个空白字符
  • class="game"按字面意思匹配
  • \s*匹配任意数量的空白字符
  • >按字面意思匹配
  • \s*匹配任意数量的空白字符
  • <img按字面意思匹配
  • \s+匹配一个或多个空白字符
  • src="按字面意思匹配
  • \K重置报告的匹配的起点。最终匹配中不再包含任何以前消费的字符
  • [^"]*匹配集合中不存在的任何字符(除"以外的任何字符)
  • (?="\s*>\s*</div>)确定后续匹配的正向前瞻
    • "按字面意思匹配
    • \s*匹配任意数量的空白字符
    • >按字面意思匹配
    • \s*匹配任意数量的空白字符
    • </div>按字面意思匹配

注意:正则表达式由/以外的字符分隔(链接使用@,PHP允许这样做。)

答案 1 :(得分:1)

强制性“不要使用正则表达式解析HTML”答案。

$dom = new DOMDocument();
$dom->loadHTML($input_lines);
$xpath = new DOMXPath($dom);
$images = $xpath->query("//div[@class='game']/img");
$sources = [];
foreach($images as $image) {
    $sources[] = $image->getAttribute("src");
}
var_dump($sources);

就我个人而言,即使您不了解XPath语法,我认为这样做会更加明显,即使您不知道XPath语法。