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

时间:2016-08-04 17:08:49

标签: php regex markdown markup

我尝试使用正则表达式匹配标记:

.push

这应该导致

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

这两个都可以正常使用这个preg_replaces:

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

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

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

它应该检查是否只有一个([^\[]{0,})(\[)([^\[]{1,})( )(.*)(]) 并且之后的char不是[。但它仍与[中的[Internal Link]匹配,但它应完全忽略此部分

1 个答案:

答案 0 :(得分:1)

使用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为空(但已定义)。回调函数必须测试它以知道哪个分支成功并返回相应的替换字符串。

相关问题