正则表达式与preg_match_all

时间:2012-11-22 09:24:30

标签: php

使用正则表达式时遇到问题:

php> $html = "<html><head><body><h1>hello world</h1><img src=\"data:rawIMGdata\" /><p/><img src=\"sdfsdf.jpg\" title=\"pic1\" /><p/><div class=\"myclass\"><img src=\"data:imageData\" /></div><img alt=\"bla\" src=\"bla.jpg\" title=\"bla\" /></body></html>";
php> $pat = '/<img.*src="(data:.*)"/m';
php> preg_match_all($pat, $html, $matching);
php> var_dump($matching);
array(2) {
  [0]=>
  array(1) {
    [0]=>
    string(169) "<img src="data:rawIMGdata" /><p/><img src="sdfsdf.jpg" title="pic1" /><p/><div class="myclass"><img src="data:imageData" /></div><img alt="bla" src="bla.jpg" title="bla""
  }
  [1]=>
  array(1) {
    [0]=>
    string(63) "data:imageData" /></div><img alt="bla" src="bla.jpg" title="bla"
  }  
}

我的预期输出只是第二个数组中出现的“data:imageData”,而且应该有两个匹配(“data:rawIMGdata”)

我是否以错误的方式定义了我的正则表达式?

此致 Broncko

4 个答案:

答案 0 :(得分:1)

你可能想考虑使用DOM Document来解析HTML,虽然如果这个例子很复杂,那么你可能会使用正则表达式;但是DOM文档总是更加健壮。

试试这个:

/<img.*?src="(data:[^"]*)"/m

?将*设置为非贪婪(因此它将获得最小匹配,默认情况下它会尽可能多地抓取)

而不是匹配任何东西,你可以匹配任何不是“with [^”]的东西。

之前的。*是贪婪的并且匹配到“在另一个元素中

答案 1 :(得分:1)

你基本上告诉PCRE要抓住太多信息。正则表达式匹配运算符将尽可能匹配,这就是为什么你在匹配中获得了额外的东西。首先,切换到使用非贪婪变量来匹配初始空格,或者匹配元素的内容。其次,引入适当的分隔符以匹配属性内容的结尾。这是你应该使用的模式:

$pat = '/<img.*?src="(data:[^"]*)"/m';

答案 2 :(得分:1)

如果您尝试解析有效​​(几乎有效)的HTML,可以尝试使用tools just for parsing XML DOM,这样您就可以非常有效地浏览XML。

RegExp肯定会完成这项工作,但是一旦您将'换成"或html从<img src="">更改为<img class="" src="">,您可能会遇到问题。

XML解析工具通常也会关注转义和“取消转义”参数,处理重复的参数。

例如,使用DOMxPath(此处为[tutorial]):

$doc = new DOMDocument;
$doc->Load('book.xml');
$xpath = new DOMXPath($doc);
$query = '//img';

$entries = $xpath->query($query);

foreach ($entries as $entry) {
    if( !$entry->hasElement('src')){
        continue;
    }

    $src = $entry->getAttribute( 'src');

    if( strncmp( $src, 'data:', 5) != 0){
       continue;
    }

    $content = substr( $src, 5);

    // Do whatever you need
}

答案 3 :(得分:0)

尝试使用'懒惰'表达式 -

$pat = '/<img(.*?)src="(data:.*)"/m';

更多信息:http://www.regular-expressions.info/repeat.html