所以,我希望在php中将以下链接结构与preg_match_all匹配..
<a garbage href="http://this.is.a.link.com/?query=this has invalid spaces" possible garbage>
<a garbage href='http://this.is.a.link.com/?query=this also has has invalid spaces' possible garbage>
<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters possible garbage>
<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters>
我可以通过
获得“和'deilmited url'#<a[^>]*?href=("|\')(.*?)("|\')#is'
或者我可以获得全部3,但如果前两个中有空格,则不会:
'#<a[^>]*?href=("|\')?(.*?)[\s\"\'>]#is'
我如何制定这个,以便它可以选择“和”用潜在的空格分隔,但也可以正确编码没有分隔符的URL。
答案 0 :(得分:1)
好的,这似乎有效:
'#<a[^>]*?href=((["\'][^\'"]+["\'])|([^"\'\s>]+))#is'
($ matches [1]包含网址)
唯一的烦恼是被引用的网址仍然有引号,所以你必须将它们剥离:
$first = substr($match, 0, 1);
if($first == '"' || $first == "'")
$match = substr($match, 1, -1);
答案 1 :(得分:1)
编辑:我编辑了这个比我最初发布的要好一点。
你几乎在第二个正则表达式中拥有它:
'#<a[^>]*?href=("|\')?(.*?)[\\1|>]#is'
返回以下数组:
array(3) {
[0]=>
array(4) {
[0]=>
string(92) "<a garbage href="http://this.is.a.link.com/?query=this has invalid spaces" possible garbage>"
[1]=>
string(101) "<a garbage href='http://this.is.a.link.com/?query=this also has has invalid spaces' possible garbage>"
[2]=>
string(94) "<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters possible garbage>"
[3]=>
string(77) "<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters>"
}
[1]=>
array(4) {
[0]=>
string(1) """
[1]=>
string(1) "'"
[2]=>
string(0) ""
[3]=>
string(0) ""
}
[2]=>
array(4) {
[0]=>
string(74) "http://this.is.a.link.com/?query=this has invalid spaces" possible garbage"
[1]=>
string(83) "http://this.is.a.link.com/?query=this also has has invalid spaces' possible garbage"
[2]=>
string(77) "http://this.is.a.link.com/?query=no_spaces_but_no_delimiters possible garbage"
[3]=>
string(60) "http://this.is.a.link.com/?query=no_spaces_but_no_delimiters"
}
}
有或没有分隔符。
答案 2 :(得分:1)
使用DOM解析器。您无法使用正则表达式解析(x)HTML。
$html = <<<END
<a garbage href="http://this.is.a.link.com/?query=this has invalid spaces" possible garbage>
<a garbage href='http://this.is.a.link.com/?query=this also has has invalid spaces' possible garbage>
<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters possible garbage>
<a garbage href=http://this.is.a.link.com/?query=no_spaces_but_no_delimiters>
END;
$domd = new DOMDocument();
libxml_use_internal_errors(true);
$domd->loadHTML($html);
libxml_use_internal_errors(false);
$items = $domd->getElementsByTagName("a");
foreach ($items as $item) {
var_dump($item->getAttribute("href"));
}
答案 3 :(得分:0)
当您说要匹配它们时,您是尝试从链接中提取信息,还是只是找到带有href的超链接?如果你只追求后者,这应该可以正常工作:
/<a[^>]*href=[^\s].*?>/
答案 4 :(得分:0)
正如@JasonWoof指出的那样,您需要使用嵌入式替换:引用URL的一种替代方法,一种用于非引用的URL。我还建议使用捕获组来确定正在使用哪种报价,正如@DanHorrigan所做的那样。通过添加负前瞻((?!\\2)
)和占有量词(*+
),您可以创建一个非常强大的正则表达式,也很快:
~
<a\\s+[^>]*?\\bhref=
(
(["']) # capture the opening quote
(?:(?!\\2).)*+ # anything else, zero or more times
\\2 # match the closing quote
|
[^\\s>]*+ # anything but whitespace or closing brackets
)
~ix
See it in action on ideone.(加倍的反斜杠是因为正则表达式是以PHP heredoc的形式编写的。我更喜欢使用nowdoc,但是ideone显然仍在运行PHP 5.2。)