使用 preg_replace 从括号内的文本制作 link

Make link from text inside brackets using preg_replace

我想使用 PHP 将文本转换为这种格式:

foo [[http://www.google.com|This Link points to google]] foo

至此

foo <a href="http://www.google.com">This Link points to google</a> foo

我做了这个代码:

function linkLine($line) {
    if (preg_match('#\[\[(.*?)\]\]#', $line, $match)) {
        $arr = explode("|", $match[1], 2);
        $link = "<a href=\"$arr[0]\">$arr[1]</a>";
        return str_replace($match[0], $link, $line);
    } else {
        return $line;
   }
}

但我知道这不优雅,不稳健,如果在同一行中出现不止一次,则不起作用。

如何使用 preg_replace 改进它?

您可以使用相同的正则表达式 preg_replace_callback:

$re = '/\[\[(.*?)]]/';
$str = 'foo [[http://www.google.com|This Link points to google]] foo [[http://www.more.com|This Link points to more]]';
echo preg_replace_callback($re, function($m) { 
    $arr = explode("|", $m[1], 2);
    return '<a href="' . $arr[0] . '">'. $arr[1] . '</a>'; 
}, $str);

参见PHP demo

结果:

foo <a href="http://www.google.com">This Link points to google</a> foo <a href="http://www.more.com">This Link points to more</a>

如果[[]]里面的字符串不能有[,]只有1个|,也可以用

$re = '/\[\[([^][|]*?)\|([^][]*?)]]/';

见下文PHP demo

$re = '/\[\[([^][|]*?)\|([^][]*?)]]/';
$str = 'foo [[http://www.google.com|This Link points to google]] foo [[http://www.more.com|This Link points to more]]';
echo preg_replace($re, '<a href=""></a>', $str);

就我个人而言,我认为 'style' 在使用正则表达式进行文本操作时的优先级较低。在我看来,在该列表中排名靠前的是首要的功能:它是否有效?伟大的。其次是可读性:其他人能否理解它在做什么,如果有 error/mistake,他们是否可以轻松修复它?

也就是说,您改进它的动机是有效的,因为它未满足您的一项功能要求,也就是说,如果同一行中多次出现。

那么为什么不逐步解决这个问题呢:

1) 将第一次出现的“[[”替换为“

2) 替换第一次出现的“|”在 '[[' 和 '">' 之后。

(这是一个棘手的问题,因为它需要您做出决定。对于以下示例,您更喜欢两种结果中的哪一种?:

3) foo [[http://www.google.com|This Link 指向]] google]] foo

我将使用“]]”的第一个实例。如果你想捕获外括号,那么你需要使用 lookaheads 来检查以确保在 '[[ '.

之前没有更多的 ']] '

按照上述步骤,我想出了(在javascript中,所以我可以举个例子):

let regex = /(.*)(\s\[\[)(http:\/\/[^|]+)(\|)((.*)(?=\b)(\]\]\s))(.*)/;

let result = "foo [[http://www.google.com|This Link points to google]] foo".replace(regex,' <a href=""/></a> ');

let pathologicalDataResult = "foo [[http://ww[[w.google.co|m|This Link poi]]nts to google]] foo".replace(regex,' <a href=""/></a> ');

console.log(result);
console.log(pathologicalDataResult);