如何在PHP中将http://或www替换为<a href..

7
我已经创建了这个正则表达式。
(www|http://)[^ ]+

我希望能够匹配所有的http://...或者www....,但我不知道如何使用preg_replace实现这个功能。我已经尝试过了。

preg_replace('/((www|http://)[^ ]+)/', '<a href="\1">\1</a>', $str);

但是它没有起作用,结果为空字符串。

复制:https://dev59.com/53RB5IYBdhLWcg3wyqOo - Sasha Chedygov
6个回答

14

由于您使用斜杠作为定界符,因此您需要在正则表达式中转义斜杠。您也可以使用其他符号作为定界符。

// escaped
preg_replace('/((www|http:\/\/)[^ ]+)/', '<a href="\1">\1</a>', $str);

// another delimiter, '@'
preg_replace('@((www|http://)[^ ]+)@', '<a href="\1">\1</a>', $str);

2
恭喜!你是唯一一个没有从混乱中复制错误正则表达式的人。 - Gumbo
1
它不会自动在www之前添加http://,所以它并不完全正确:www.google.com将变成<a href="www.google.com">...而不是<a href="http://www.google.com">。 - Thanh Trung
当URL末尾是“<br>”时,代码无法正常工作,因此需要将“<br>”添加到URL中。 - user956584
你能不能至少修复一下你的代码?它连 https 都处理不了...-.- - Playdome.io
preg_replace('/((www|http://)[^,\n ]+)/', '<a href="\1">\1</a>', $str); 只需进行一些修改即可在遇到“,”、“换行符”时停止替换。 - chings228

2

当使用其他用户提供的正则表达式代码时,一定要添加“i”标志以启用不区分大小写,这样它就能够与HTTP://和http://都起作用。例如,使用chaos的代码:

preg_replace('!(www|http://[^ ]+)!i', '<a href="\1">\1</a>', $str);

2
首先,您需要像其他答案中所解释的那样转义或更好地替换分隔符。
preg_replace('~((www|http://)[^ ]+)~', '<a href="\1">\1</a>', $str);

其次,为了进一步改善正则表达式,建议使用$n替换引用语法,而不是\\n,正如手册中所述。
preg_replace('~((www|http://)[^ ]+)~', '<a href="$1">$1</a>', $str);

第三点,你不必要地使用了捕获括号,这只会减慢速度。把它们去掉。别忘了将 $1 更新为 $0。如果你想知道,这些是非捕获括号:(?: )
preg_replace('~(?:www|http://)[^ ]+~', '<a href="$0">$0</a>', $str);

最后,我会用更短、更准确的\S替换[^ ]+,它是\s的相反。请注意,[^ ]+不允许空格,但接受换行符和制表符!\S则不包括这些字符。
preg_replace('~(?:www|http://)\S+~', '<a href="$0">$0</a>', $str);

1
preg_replace('!((?:www|http://)[^ ]+)!', '<a href="\1">\1</a>', $str);

当您使用/作为模式分隔符时,将/放在模式内部将无法正常工作。我通过使用!作为模式分隔符来解决这个问题,但您也可以使用反斜杠转义您的斜杠。

我还没有看到您为什么要进行两个括号捕获,因此我删除了其中一个。

您所遇到的问题的一部分是您正在禁止警告;如果您打开了error_reporting(E_ALL),您将会看到PHP尝试生成有关您在正则表达式中的分隔符问题的消息。


有趣的是,大多数人在他们的示例中使用了你错误的正则表达式。 - Gumbo
我想我们都在复制 OP 的代码。不过现在已经修复了,无论如何。 - chaos

1

如果一个字符串中包含多个URL,它们之间用换行符而不是空格分隔,那么你必须使用\S。

preg_replace('/((www|http:\/\/)\S+)/', '<a href="$1">$1</a>', $val);

1

你的主要问题似乎是你把所有东西都放在括号里,所以它不知道 "\1" 是什么。此外,你需要转义 "/". 所以尝试这个:

preg_replace('/(www|http:\/\/[^ ]+)/', '<a href="\1">\1</a>', $str);

编辑:实际上,括号并不是问题,我看错了。转义仍然是一个问题,正如其他人也指出的那样。任何一个解决方案都应该可以解决。


我想补充一下,反向引用是由开括号编号的。例如,在正则表达式“T(e(st))”中,\1 包含“est”,\2 包含“st”。 - Bravery Onions

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接