antiver
问问题
651 次
3 回答
10
恭喜,您是第 100 万位询问 Stack Overflow 如何使用正则表达式解析 HTML 的客户!
[X][HT]ML 不是常规语言,不能用正则表达式可靠地解析。使用 HTML 解析器。PHP 本身为您提供DOMDocument,或者您可能更喜欢simplehtmldom。
顺便说一句,您无法通过查看文件的 URL 来判断文件的类型。JPEG 没有理由必须将“.jpeg”作为其扩展名——事实上,不能保证具有“.jpeg”扩展名的文件实际上是 JPEG。唯一可以确定的方法是获取资源(例如,使用 HEAD 请求)并查看 Content-Type 标头。
于 2009-09-19T23:23:35.937 回答
7
啊,我的日常 DOM 练习。您应该使用 DOM 来解析 HTML,并使用正则表达式来解析字符串,例如 html 属性。
注意:我有一些基本的正则表达式肯定可以被一些向导改进:)
注意#2:虽然这可能会产生额外的开销,但您可以使用 curl 之类的方法通过发送 HEAD 请求并查看 Content-Type 来彻底检查 href 是否为实际图像,但这在 80-90% 的情况下有效.
<?php
$content = '
<a href="http://www.domain.tld/any/valid/path/to/imagefile.ext">This will be ignored.</a>
<br>
<a href="http://col.stb.s-msn.com/i/43/A4711309495C88F8CD154C99FCE.jpg">this will not be ignored</a>
<br>
<a href="http://col.stb.s-msn.com/i/A0/8E9A454F701E4F5F89E58E14B532C.jpg">bah</a>
';
$dom = new DOMDocument();
$dom->loadHTML($content);
$anchors = $dom->getElementsByTagName('a');
$i = $anchors->length-1;
$protocol = '/^http:\/\//';
$ext = '/([\w+]+)\.(?:gif|jpg|jpeg|png)$/';
if ( count($anchors->length) > 0 ) {
while( $i > -1 ) {
$anchor = $anchors->item($i);
if ( $anchor->hasAttribute('href') ) {
$link = $anchor->getAttribute('href');
if (
preg_match ( $protocol , $link ) &&
preg_match ( $ext, $link )
) {
//echo 'replacing this one.';
$image = $dom->createElement('img');
if ( preg_match( $ext, $link, $matches ) ) {
if ( count($matches) ) {
$altName = $matches[1];
$image->setAttribute('alt', $altName);
}
$image->setAttribute('src', $link);
$anchor->parentNode->replaceChild( $image, $anchor );
}
}
}
$i--;
}
}
echo $dom->saveHTML();
于 2009-09-19T23:22:27.313 回答
1
我建议使用这个更灵活的非 greddy 正则表达式:
<a[^>]+?href=\"(http:\/\/[^\"]+?\/([^\"]*?)\.(jpg|jpeg|png|gif))[^>]*?>[^<]*?<\/a>
还有一个更复杂的正则表达式(包括 PHP 测试代码),希望能取悦 Gumbo :)
<?php
$test_data = <<<END
<a blabla="asldlsaj" alksjada="aslkdj" href="http://www.domain.tld/any/valid/path/to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
Lorem ipsum..
<a blabla=asldlsaj alksjada="aslkdj" href="http://www.domain.tld/any/valid/path/to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
<a lkjafs='asdsa> ' blabla="asldlksjada=>"aslkdj" href="http://www.domain.tld/any/valid/path/to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
<a blabla="ajada="aslk href="http://www.domain.tld/any/valid/path>/to/imagefile.jpg" lkjasd>asdlaskjd>This will be ignored.</a>
<a blabla="asldlsaj>" aslkdj href="http://www.domain.tld/any/valid/path/ to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
Something:
<a blabla='asldls<ajslkdj' href="http://www.domain.tld/any/valid'/path/to/imagefile.jpg" lkjasd=""asdlaskjd>This will be ignored.</a>
<a blabla= asldlsadj href="http://www.domain.tld/any/valid/path/to/imagefile.jpg" lkjasd>This will be ignored.</a>
<a blabla="asldlsaj" alksjslkdj" href='http://www.domain.tld/any/valid/path/to/imagefile.jpg' lkjasdskjd>This will be ignored.</a>
Something else...
<a blabla="asldlsaj" alksjslkdj" href='http://www.domain.tld/any/valid/path/to/imagefile.jpg' lkjasdskjd>This will be ignored.</a>
<a blabla="asldlsaj" alksjada="aslkdj" href=http://www.domain.tld/any/valid/path/to/imagefile.jpg lkjdlaskjdll> be ignored.</a>
END;
$regex = "/<a\s(\s*\w+(\s*=\s*(\".*?\"|'.*?'|[^'\">\s]+))?)+?\s+href\s*=\s*(\"(http:\/\/[^\"]+\/(.*?)\.(jpg|jpeg|png|gif))\"|'(http:\/\/[^']+\/(.*?)\.(jpg|jpeg|png|gif))'|(http:\/\/[^'\">\s]+\/([^'\">\s]+)\.(jpg|jpeg|png|gif)))\s(\s*\w+(\s*=\s*(\".*?\"|'.*?'|[^'\">\s]+))?)+>[^<]*?<\/a>/i";
$replaced = preg_replace($regex, '<img src="$5$8$11" alt="$6$9$12" />', $test_data);
echo '<pre>'.htmlentities($replaced);
?>
于 2009-11-15T15:12:42.707 回答