【问题标题】:How do I fix this URL regexp to match URLs at the end of the string?如何修复此 URL 正则表达式以匹配字符串末尾的 URL?
【发布时间】:2015-06-09 19:42:21
【问题描述】:

我从此处的另一个答案中找到了与regexp 匹配的很棒的 URL,该答案在字符串中获取 URL,但只有在它们后跟空格时才有效。

preg_replace('#(https?|ftp)://[^ ]+ #i', '', $s['Text']);

我将如何修改它以使其也匹配位于字符串末尾且后面没有任何内容的 URL?

【问题讨论】:

  • 但是它匹配在 http:// 之后输入的所有内容,并且不等待有效的扩展名。不过感谢您的建议!
  • 一个不会让你的正则表达式更好地拒绝无效 URL 的简单修复是 preg_replace('#(https?|ftp)://[^\s\r\n]+(?:$|[\s\r\n])#i', '', $s['Text']);。这将匹配字符串的结尾或任何空格。您可能还想看一下regular-expressions.info 教程左右,它还将解释非捕获组(?:...) 和前瞻,这可能会有所帮助。
  • 您能否将答案链接到您找到该参考资料的位置?你有没有留下评论说它不适合你?

标签: php html regex string


【解决方案1】:

为了匹配所有类型的 URL,以下代码可以帮助您:

<?php

$content = '<html>

<title>Random Website I am Crawling</title>

<body>

Click <a href="http://clicklink.com">here</a> for foobar

Another site is http://foobar.com';

$regex = "((https?|ftp)\:\/\/)?"; // SCHEME
$regex .= "([a-z0-9+!*(),;?&=\$_.-]+(\:[a-z0-9+!*(),;?&=\$_.-]+)?@)?"; // User and Pass
$regex .= "([a-z0-9-.]*)\.([a-z]{2,4})"; // Host or IP
$regex .= "(\:[0-9]{2,5})?"; // Port
$regex .= "(\/([a-z0-9+\$_-]\.?)+)*\/?"; // Path
$regex .= "(\?[a-z+&\$_.-][a-z0-9;:@&%=+\/\$_.-]*)?"; // GET Query
$regex .= "(#[a-z_.-][a-z0-9+\$_.-]*)?"; // Anchor


$matches = array(); //create array
$pattern = "/$regex/";

preg_match_all($pattern, $content, $matches); 

print_r(array_values(array_unique($matches[0])));
echo "<br><br>";
echo implode("<br>", array_values(array_unique($matches[0])));


?>

【讨论】:

  • 嘿阿德里安,我刚刚注意到这个正则表达式从youtube.com/watch?v=9GorqroigqM 中删除了“9GorqroigqM” - 关于如何解决这个问题的任何建议?它似乎赶上了 =
  • 重要提示:此正则表达式不接受超过 4 个字符的新 TLD、本地 TLD、带下划线的非标准名称或任何 Unicode/UTF-8 域名 (IDN)。此外,使用扩展的 PCRE 语法可能比串联更好(虽然没有尝试过)。使用正则表达式中未使用的分隔符字符也可以删除一些转义。
  • 谢谢@Archimedix - 你有更好的推荐吗?
  • @MichaelF 严格来说并不是更好,因为它也会匹配像 http://;@!? 这样的非 URL,但至少没有误报(无法识别的有效 URL),并且更接近您的正则表达式,请参阅我对您问题的评论.
猜你喜欢
  • 2019-09-13
  • 1970-01-01
  • 1970-01-01
  • 2019-12-18
  • 1970-01-01
  • 2010-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多