正则表达式:忽略两个括号的匹配

Regex: ignoring match with two brackets

我尝试通过正则表达式匹配标记:

1. thats an [www.external.com External Link], as you can see
2. thats an [[Internal Link]], as you can see

这应该导致

1. thats an [External Link](www.external.com), as you can see
2. thats an [Internal Link](wiki.com/Internal Link), as you can see

两者都适用于此 preg_replaces:

1. $line = preg_replace("/(\[)(.*?)( )(.*)(\])/", "[]()", $line);            
2. $line = preg_replace("/(\[\[)(.*)(\]\])/",   "[](wiki.com/)", $line);

但它们相互干扰,所以使用一个接一个地替换 returns 丑陋的结果。所以我试图在一场比赛中忽略另一场比赛。我试图用这个替换第一个正则表达式:

([^\[]{0,})(\[)([^\[]{1,})( )(.*)(])

它应该检查是否只有一个 [ 并且之前和之后的字符不是 [。但它仍然匹配[]中的[Internal Link],但它应该完全忽略这部分

使用 preg_replace_callback 您可以构建一个模式来处理这两种情况并在回调函数中定义条件替换。这样字符串只被解析一次。

$str =  <<<'EOD'
1. thats an [www.external.com External Link], as you can see
2. thats an [[Internal Link]], as you can see
EOD;

$domain = 'wiki.com';
$pattern = '~\[(?:\[([^]]+)]|([^] ]+) ([^]]+))]~';    

$str = preg_replace_callback($pattern, function ($m) use ($domain) {
    return empty($m[1]) ? "[$m[3]]($m[2])" : "[$m[1]]($domain/$m[1])";
}, $str);

echo $str;

该模式使用交替 (?: xxx | yyy)。第一个分支描述内部链接,第二个分支描述外部链接。

当第二个分支成功时,第一个捕获组 1 为空(但已定义)。回调函数必须对其进行测试以了解哪个分支成功并 return 适当的替换字符串。