使用正则表达式时遇到问题:
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
答案 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';