我使用re2 / J来提取URL,无论它们是否以正则表达式开头。 我使用的是一种相当简单的模式,
(?i)((https?://)?(([a-z0-9\\-]+[.])*([a-z0-9\\-]+[.][a-z]+/?)([^\\s()<>]*)))
然而,我在开头和结尾添加\ b是\ b对我没什么帮助。它仍然匹配作为电子邮件一部分的网址。
来自电子邮件@ example.com 的example.com也将匹配。我试图避免的东西。 @ 被视为非单词字符,因此\ b将其视为单词边界。这个问题有一个很好的替代解决方案吗?
编辑:
请注意,我正在尝试用html锚标记替换网址,所以我实际上并不是在寻找匹配项。我必须指定一个模式并用捕获的组替换。
答案 0 :(得分:1)
通常&#34;技巧&#34;当你需要&#34;跳过&#34;一些匹配并替换另一个是匹配并捕获您需要的东西,并匹配您不需要的东西。由于替换模式对于两种上下文都不同,因此您应该能够分析匹配对象,Matcher#appendReplacement
提供此功能:
String s = "some@domain.com\ndomain.com\nwww.domain.com\nhttp://www.domain.com\nhttps://www.domain.com";
StringBuffer result = new StringBuffer();
Matcher m = Pattern.compile("(?i)\\S+@\\S+\\.\\S+|((?:https?://)?(?:[a-z0-9-]+[.])*[a-z0-9-]+[.][a-z]+/?[^\\s()<>]*)").matcher(s);
while (m.find()) {
if (m.group(1) != null) {
m.appendReplacement(result, "<a href=\"" + m.group(1) + "\">" + m.group(1) + "</a>");
}
else {
m.appendReplacement(result, m.group());
}
}
m.appendTail(result);
System.out.println(result.toString()); // Demo output
Online Java demo(java.util.regex
使用相同的技术)
模式详情:
\\S+@\\S+\\.\\S+
- 匹配类似于电子邮件的内容(1 +非空白,@
,1 +非空白,.
以及1 +非空白|
- 或((?:https?://)?(?:[a-z0-9-]+[.])*[a-z0-9-]+[.][a-z]+/?[^\\s() <>]*)
- 第1组捕捉您的模式。如果组1匹配,则不是null
,我们需要将其包装到标签中。否则,jsut重新插入整场比赛。
答案 1 :(得分:0)
对于email@example.com,regex只会将e匹配为[^ @]和xample.com作为匹配的其余部分 - 它们稍后会合并为一个匹配。 只需在URL之前检查空格,但不要在子模式中包含它。