我正在尝试为使用 PHP 的聊天客户端实现非常宽松的正则表达式匹配。
聊天客户端必须能够获取完整和不完整的 URL。
例如:
http://www.example.com
或 www.example.com
或 example.com
我已经设置了一个 preg_replace 来尝试实现这一点:
$find = array("/([\w]+:\/\/[\w-?&;#~=\.\/\@]+[\w\/])/is","/(^(?!http:\/\/)[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,4}(\/?\S*)?)/is");
$replace = array( "<a target=\"_blank\" href=\"http://\\1\">\\1</a>","<a target=\"_blank\" href=\"\\1\">\\1</a>");
$output = preg_replace($find, $replace, $input);
因此,目标是首先找到具有协议(protocol)的“完整”URL,然后尝试找到没有协议(protocol)的“惰性”URL。
目前它对“完整”的 URL 非常有效,但“惰性”的 URL 不会被拾取。
最佳答案
我刚才设置了类似的东西。我的想法是……任何以协议(protocol)标识符或“www”开头的内容都是 URL,加上任何与以有效 TLD(两个字母或已知 gTLD)结尾的域匹配的内容(如果它后跟路径)。域本身就是域。
$gtlds="com|net|org|biz|edu|gov|int|pro|xxx";
$gtlds+="|aero|arpa|asia|coop|museum|name|travel";
#$gtlds+="|xn-[a-z0-9]+";
$a = array(
'/(f|ht)tps?:\/\/[^ ]+/',
'/(ftp|www)\.[a-z0-9.-]+(/[^ ]*)/',
"/([a-z0-9][a-z0-9-]*\.)+([a-z]{2}|$gtlds)\/[^ ]*/"
);
请注意,我是一个老派的正则表达式用户,所以这是 ERE,而不是现在所有 child 都在使用的花哨的 PREG 东西。
长得离谱的 gTLD 列表来自 IANA .我已经更新了它,所以它在回答时有效,.XN--*
除外。如果愿意,您可以包含以 .XN--
开头的 TLD 列表,可以使用模式或直接匹配它们并增加 $gtlds
变量。我从来没有遇到过因为简单地忽略它们的存在而导致的任何问题,所以这就是我的策略。
上述 RE 适合我的特定用途。我并没有声称它们适用于所有不是我的案例。 (例如,如果引用域或 URL,它们将包含尾随引号。这从来不是我必须处理的事情,所以我没有处理它。)
请注意,当您进行替换时,虽然您希望生成器 anchor 的 HREF 属性是您匹配或生成的 URL,但出于布局和显示的目的,您可能希望保留原始文本。
根据您使用它们的方式,单词边界可能会有所帮助……但您已经知道如何使用它们。
关于php - Twitter 风格的 URL 正则表达式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11069027/