JavaScript 正则表达式匹配文本字段中的 URL

IT技术 javascript jquery regex
2021-03-15 21:49:36

如何设置我的正则表达式以测试 URL 是否包含在 javascript 的文本块中。我无法弄清楚用于完成此操作的模式

 var urlpattern = new RegExp( "(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?"

 var txtfield = $('#msg').val() /*this is a textarea*/

 if ( urlpattern.test(txtfield) ){
        //do something about it
 }

编辑:

所以我现在拥有的模式可以在正则表达式测试器中用于我需要它做的事情,但 chrome 会引发错误

  "Invalid regular expression: /(http|ftp|https)://[w-_]+(.[w-_]+)+([w-.,@?^=%&:/~+#]*[w-@?^=%&/~+#])?/: Range out of order in character class"

对于以下代码:

var urlexp = new RegExp( '(http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&:/~\+#]*[\w\-\@?^=%&/~\+#])?' );
6个回答

尽管转义破折号字符(在字符类中可以作为字符范围说明符具有特殊含义)应该可以工作,但另一种去除它们特殊含义的方法是将它们放在类定义的开头或结尾。

此外,\+\@在字符类确实解释为+@分别由JavaScript引擎; 但是,转义不是必需的,并且可能会使试图从视觉上解释正则表达式的人感到困惑。

我会为您的目的推荐以下正则表达式:

(http|ftp|https)://[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?

这可以在 JavaScript 中指定,方法是将其传递给 RegExp 构造函数(就像您在示例中所做的那样):

var urlPattern = new RegExp("(http|ftp|https)://[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?")

或直接指定正则表达式文字,使用//引用方法:

var urlPattern = /(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])?/

如果您接受正则表达式作为字符串(例如来自用户输入或 AJAX 调用),则 RegExp 构造函数是必要的,并且可能更具可读性(就像在这种情况下一样)。我相当肯定//引用方法更有效,并且在某些时候更具可读性。两者都有效。

我在 < JSFiddle > 和 < RegexLib.com >上使用 Chrome 测试了您的原始和此修改,使用客户端正则表达式引擎(浏览器)并特别选择了 JavaScript。虽然第一个因您所说的错误而失败,但我建议的修改成功了。如果我hhttp源中删除,它将无法匹配,因为它应该!

编辑

正如@noa 在评论中所指出的,上面的表达式将不匹配本地网络(非互联网)服务器或任何其他用单个词(例如http://localhost/……或https://sharepoint-test-server/……)访问的服务器如果需要匹配这种类型的 url(可能是也可能不是),以下可能更合适:

(http|ftp|https)://[\w-]+(\.[\w-]+)*([\w.,@?^=%&amp;:/~+#-]*[\w@?^=%&amp;/~+#-])?

#------changed----here-------------^

<结束编辑>

最后,一个很好的资源教会了我 90% 的关于正则表达式的知识是正则表达式.info - 如果你想学习正则表达式(它能做什么和不能做什么),我强烈推荐它!

这会破坏主机中没有点的 URL。例如,http://localhost/foo/bar.txt要修复它,请更改(\.[\w-]+)+(\.[\w-]+)*
2021-04-24 21:49:36
正则表达式信息已损坏。在 href 中放置“点”而不是破折号。
2021-04-28 21:49:36
还有一件事:正确的语法是... = new RegExp(...)而不是... = new Regexp(...). 无论如何,感谢您的出色回答!
2021-05-02 21:49:36
我强烈推荐它作为补充资源:mathiasbynens.be/demo/url-regex
2021-05-03 21:49:36
这个问题很笼统,这个答案得到了很多认可。有人(不是 OP)使用了这段代码,它在我正在调试的一些代码中造成了一个真正的错误……所以中断并不完全是相对的。使答案尽可能规范是值得的。
2021-05-07 21:49:36

完整的多 URL 模式。

更新:2020 年 11 月、2021 年 4 月和 6 月(感谢评论者)

匹配字符串中的所有 URI 或 URL! 还提取协议、域、路径、查询和哈希。([a-z0-9-]+\:\/+)([^\/\s]+)([a-z0-9\-@\^=%&;\/~\+]*)[\?]?([^ \#\r\n]*)#?([^ \#\r\n]*)

https://regex101.com/r/jO8bC4/56

带有输出的示例 JS 代码 - 每个 URL 都被转换为其“部分”(协议、主机、路径、查询和哈希)的 5 部分数组

var re = /([a-z0-9-]+\:\/+)([^\/\s]+)([a-z0-9\-@\^=%&;\/~\+]*)[\?]?([^ \#\r\n]*)#?([^ \#\r\n]*)/mig;
var str = 'Bob: Hey there, have you checked https://www.facebook.com ?\n(ignore) https://github.com/justsml?tab=activity#top (ignore this too)';
var m;

while ((m = re.exec(str)) !== null) {
    if (m.index === re.lastIndex) {
        re.lastIndex++;
    }
    console.log(m);
}

会给你以下内容:

["https://www.facebook.com",
  "https://",
  "www.facebook.com",
  "",
  "",
  ""
]

["https://github.com/justsml?tab=activity#top",
  "https://",
  "github.com",
  "/justsml",
  "tab=activity",
  "top"
]
这是一个超级聪明的方法+1
2021-04-21 21:49:36
嘿@vsync - 谢谢,它现在需要域的 1 个或多个字符!
2021-04-24 21:49:36
您的正则表达式不区分文本块和 URL。在这里查看
2021-05-09 21:49:36
BAM "a a:// . "返回true此正则表达式:/
2021-05-12 21:49:36
更新了我的答案 - 包括 @noob 的建议字符串附加到我的示例代码中(因此它非常可靠地提取所有类似 url 的字符串 - 即使有冒号前缀的字符串。使用斜杠上的显式匹配来描述协议)。也适用于smb:///winbox/dfs/ipp://printer regex101.com/r/jO8bC4/5
2021-05-18 21:49:36

使用new RegExp.

您也可以将破折​​号-放在字符类的末尾以避免转义它。

&amp;在字符类中意味着& or a or m or p or ;,您只需要放置&;a, m and p都已经匹配了\w

所以,你的正则表达式变成:

var urlexp = new RegExp( '(http|ftp|https)://[\\w-]+(\\.[\\w-]+)+([\\w-.,@?^=%&:/~+#-]*[\\w@?^=%&;/~+#-])?' );
如何扩展它以匹配多个网址?
2021-04-28 21:49:36

尝试 (http|ftp|https):\/\/[\w\-_]+(\.[\w\-_]+)+([\w\-\.,@?^=%&amp;:/~\+#]*[\w\-\@?^=%&amp;/~\+#])?

使用它时,我在字符类中收到错误 Range out of order”
2021-05-19 21:49:36

我已经清理了你的正则表达式:

var urlexp = new RegExp('(http|ftp|https)://[a-z0-9\-_]+(\.[a-z0-9\-_]+)+([a-z0-9\-\.,@\?^=%&;:/~\+#]*[a-z0-9\-@\?^=%&;/~\+#])?', 'i');

经过测试并且工作正常;)

添加“全局”修饰符 (g):new RegExp(.., 'gi')
2021-04-20 21:49:36
如何扩展它以匹配多个网址?——
2021-05-10 21:49:36