You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP环境下如何编写Perl正则匹配无前缀等号与引号的URL

解决PHP正则匹配无等号前缀URL的编译错误

你的问题出在PHP的PCRE引擎对**负向预查(lookbehind)**的限制:旧版本PHP不支持可变长度的lookbehind断言,你写的(?<!\s*=\s*['"]?\s*)里包含\s*(匹配0到任意多个空白),属于可变长度模式,导致正则编译失败。下面给出几种可行的解决方法,优先匹配你需要的http://www.url1.com/和http://www.url3.com/:

方案1:PHP 7.3+ 用有限长度lookbehind修复(推荐)

PHP 7.3及以上的PCRE2引擎支持有限长度的lookbehind,只要把可变长度的\s*换成固定最大长度的\s{0,10}(可根据实际需求调整最大空白数),就能直接修复原正则:

$html = "
http://www.url1.com/
= ' http://www.url2.com/
'http://www.url3.com/
<a href='http://www.url4.com/'>Testing1</a>
<img src='https://url5.com'>Testing2</a>";

$url_pregex = '((http(s)?://)[-a-zA-Z()0-9@:%_+.~#?&;//=]+)';
// 将\s*替换为\s{0,10},限制空白最多10个,满足有限长度要求
$pregex = '(?<!\s{0,10}=\s{0,10}[\'"]?\s{0,10})'.$url_pregex;

preg_match_all('`'.$pregex.'`i', $html, $matches);

echo "Matches<br><pre>";
var_export($matches);
echo "</pre>";

方案2:兼容低版本PHP的替代方案

如果你的PHP版本低于7.3,可以用以下两种方式绕过可变长度lookbehind的限制:

方法A:先匹配所有URL,再过滤不符合的

先提取所有URL,再通过后处理排除掉前面带有等号(含可选引号、空白)的URL:

$html = "
http://www.url1.com/
= ' http://www.url2.com/
'http://www.url3.com/
<a href='http://www.url4.com/'>Testing1</a>
<img src='https://url5.com'>Testing2</a>";

$url_pregex = '((http(s)?://)[-a-zA-Z()0-9@:%_+.~#?&;//=]+)';
preg_match_all('`'.$url_pregex.'`i', $html, $matches);

// 过滤规则:URL前不能是等号+可选引号+空白结尾的内容
$valid_matches = array_filter($matches[0], function($url) use ($html) {
    $pos = strpos($html, $url);
    if ($pos === 0) return true;
    $prefix = substr($html, 0, $pos);
    return !preg_match('`\s*=\s*[\'"]?\s*$`', $prefix);
});

echo "Matches<br><pre>";
var_export(array_values($valid_matches));
echo "</pre>";

方法B:用正向预查+\K重置匹配起点

利用\K丢弃前面的匹配内容,只捕获符合条件的URL,同时通过正向预查确保前面的内容不包含排除前缀:

$html = "
http://www.url1.com/
= ' http://www.url2.com/
'http://www.url3.com/
<a href='http://www.url4.com/'>Testing1</a>
<img src='https://url5.com'>Testing2</a>";

// 匹配任意字符直到URL,同时确保前面没有等号前缀,用\K只保留URL部分
$pregex = '`(?:^|(?!\s*=\s*[\'"]?\s*).)*?\K((http(s)?://)[-a-zA-Z()0-9@:%_+.~#?&;//=]+)`i';

preg_match_all($pregex, $html, $matches);

echo "Matches<br><pre>";
var_export($matches[1]);
echo "</pre>";

最终效果

以上所有方案都会正确匹配到目标URL:

  • http://www.url1.com/
  • http://www.url3.com/
    并排除掉属于HTML属性(href/src)或带有等号前缀的URL。

内容的提问来源于stack exchange,提问作者developer981

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 23:15:56