如何使用正则表达式将网址作为单词匹配而不使用标准单词边界?

时间:2016-12-08 07:04:47

标签: java regex re2

我使用re2 / J来提取URL,无论它们是否以正则表达式开头。 我使用的是一种相当简单的模式,

(?i)((https?://)?(([a-z0-9\\-]+[.])*([a-z0-9\\-]+[.][a-z]+/?)([^\\s()<>]*)))

然而,我在开头和结尾添加\ b是\ b对我没什么帮助。它仍然匹配作为电子邮件一部分的网址。

来自电子邮件@ example.com 的example.com也将匹配。我试图避免的东西。 @ 被视为非单词字符,因此\ b将其视为单词边界。

这个问题有一个很好的替代解决方案吗?

编辑:

请注意,我正在尝试用html锚标记替换网址,所以我实际上并不是在寻找匹配项。我必须指定一个模式并用捕获的组替换。

2 个答案:

答案 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 demojava.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之前检查空格,但不要在子模式中包含它。

看看,这可以帮到你。 preg_match_all to find all URL but exclude email