正如其他人说,首先需要定义什么是“链接”。 (请注意,“链接”仅是此上下文中的“超链接”的缩写,因此您的句子没有意义。)考虑到您的两个示例,您希望匹配Uniform Resource Identifiers (URIs)和Fully Qualified Domain Names (FQDNs)。
为了做到这一点,你应该采取的正则表达式可以在RFC 3986, Appendix B发现 -
^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?
- 它变成一个在单词边界匹配,只接受//
后FQDN和可选的端口号,并且停止在空白(\s
):
,----scheme----. ,-Fully Qualified Domain Name-.,-port.,--path--.,---query----.,fragment
| | | || || || || |
(^|\s)(([^:/?#\s]+):)?(//([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?
然后你就可以使方案部分可选 -
|
v
(^|\s)((([^:/?#\s]+):)?//)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?
- 写这是一个正则表达式文本(式中斜杠需要进行转义,因为他们作为分隔符):
/(^|\s)((([^:\/?#\s]+):)?\/\/)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+)(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?/
(您可能要匹配IDNs过; JSX:regexp.js及其对Unicode字符属性的支持可以帮助您,请参阅How to remove all characters from a string。你可能要预先考虑到FQDN子表达式为用户名的URI,(\[email protected])?
可选的和过时传输的子表达式,用于代理访问)。
然后你就可以更换所有字符串(g
叶形的修改),其这将匹配相应的a
元素:
var rx = /(^|\s)(((([^:\/?#\s]+):)?\/\/)?(([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+)(:\d+)?([^?#\s]*)(\?([^#\s]*))?(#(\S*))?)/g;
str = str.replace(rx,
function (match, optionalWhitespace, uri, scheme, p4, protocol, fqdn, p7, port,
path, query, queryVal, fragment, fragId) {
return (optionalWhitespace ? optionalWhitespace : '')
+ '<a href="' + (protocol ? uri : 'http://' + uri)
+ '" target="_blank">' + uri + '<\/a>';
});
必须假定在这里,当你看到的只是一个FQDN前缀,它是一个没有安全网站的域名,并在前面加上http://
。否则,href
属性中的URI参考将引用您的网站中可能存在的路径,该网站以域名作为其名称(http://your-site.example/other-site.example.com
),这可能不是您想要的。
这是可能的,但不太可能,这个表达式匹配你的情况太多;用尽可能多的输入进行测试,并根据需要进行调整。如果向后兼容性不是问题,请使用non-capturing parentheses((?:…)
)来提高效率和减少命名参数;详情请参阅ECMAScript Support Matrix。
捕获FQDN部分 - 围绕([A-Za-z0-9-]+\.)+[A-Za-z0-9-]+
的括号是可选的;你可能想用它来给a
元素一个class
属性值,以特殊的方式对它进行格式化,比如预先添加一个适配图标,例如指向Stack Overflow,Wikipedia,Twitter或Facebook的链接。
您可能还想重新考虑使用target
属性(for Strict (X)HTML, you MUST remove it)。用户可能不善于不控制链接目标的打开位置。改为以标题,图标,光标等形式提供提示。
如果没有协议,很难弄清楚什么是链接。人们有时会这样写。这是一个链接吗? :) – KillerX
你会努力去匹配“stackoverflow.com”而不会冒险将文本转换为人们并不打算成为的链接。 – crdx
好的我应该怎么做才能像上面提到的那样? – Sedz