我正在尝试使用preg_replace将纯链接转换为HTML链接。然而,它正在替换已经转换的链接。
为了解决这个问题,如果链接以引号开头,我希望它忽略替换。
我认为可能需要积极的展望,但我所尝试的一切都没有奏效。
$string = '<a href="http://www.example.com">test</a> http://www.example.com';
$string = preg_replace("/((https?:'/'/['w]+[^ ','"'n'r't<]*))/is", "<a href='"$1'">$1</a>", $string);
var_dump($string);
上述输出:
<a href="<a href="http://www.example.com">http://www.example.com</a>">test</a> <a href="http://www.example.com">http://www.example.com</a>
何时输出:
<a href="http://www.example.com">test</a> <a href="http://www.example.com">http://www.example.com</a>
您可能会使用查找。Lookaround是零宽度断言,确保匹配/不匹配所讨论字符串周围的任何内容。它们不消耗任何字符
也就是说,在您的情况下,消极的后备可能是您需要的:
(?<![">])'bhttps?://'S+'b
在PHP
中,这将是:
<?php
$string = 'I want to be transformed to a proper link: http://www.google.com ';
$string .= 'But please leave me alone ';
$string .= '(<a href="https://www.google.com">https://www.google.com</a>).';
$regex = '~ # delimiter
(?<![">]) # a neg. lookbehind
https?://'S+ # http:// or https:// followed by not a whitespace
'b # a word boundary
~x'; # verbose to enable this explanation.
$string = preg_replace($regex, "<a href='$0'>$0</a>", $string);
echo $string;
?>
请参阅ideone.com上的演示。不过,也许解析器更合适。
由于您可以在preg_replace中使用Arrays,因此使用起来可能很方便,具体取决于您想要实现的目标:
<?php
$string = '<a href="http://www.example.com">test</a> http://www.example.com';
$rx = array("&(<a.+https?:'/'/['w]+[^ ','"'n'r't<]*>)(.*)(<'/a'>)&si", "&('s){1,}(https?:'/'/['w]+[^ ','"'n'r't<]*)&");
$rp = array("$1$2$3", "<a href='"$2'">$2</a>");
$string = preg_replace($rx,$rp, $string);
var_dump($string);
// DUMPS:
// '<a href="http://www.example.com">test</a><a href="http://www.example.com">http://www.example.com</a>'
创意
您可以在已经存在的锚点处拆分字符串,并且只解析其间的部分。
守则
$input = '<a href="http://www.example.com">test</a> http://www.example.com';
// Split the string at existing anchors
// PREG_SPLIT_DELIM_CAPTURE flag includes the delimiters in the results set
$parts = preg_split('/(<a.*?>.*?<'/a>)/is', $input, PREG_SPLIT_DELIM_CAPTURE);
// Use array_map to parse each piece, and then join all pieces together
$output = join(array_map(function ($key, $part) {
// Because we return the delimiter in the results set,
// every $part with an uneven key is an anchor.
return $key % 2
? preg_replace("/((https?:'/'/['w]+[^ ','"'n'r't<]*))/is", "<a href='"$1'">$1</a>", $part)
: $part;
}, array_keys($parts), $parts);