0

使用正则表达式时出现问题:

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”)

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

问候, 布朗科

4

4 回答 4

1

您可能想要考虑使用 DOM Document 来解析 HTML,尽管如果这个示例很复杂,那么您可能会使用正则表达式;不过,DOM 文档总是会更加健壮。

试试这个:

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

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

而不是匹配任何东西,你可以用 [^"] 匹配任何不是 " 的东西。

.* 之前是贪婪的并且匹配另一个元素中的 "

于 2012-11-22T09:27:44.033 回答
1

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

$pat = '/<img.*?src="(data:[^"]*)"/m';
于 2012-11-22T09:32:49.200 回答
1

如果您尝试解析有效​​(几乎有效)的 HTML,您可以尝试使用仅用于解析 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
}
于 2012-11-22T09:39:15.270 回答
0

尝试使用“懒惰”的表达方式——

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

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

于 2012-11-22T09:32:27.713 回答