0

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

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

但是我在开头和结尾添加 \b 是 \b 对我没有多大帮助。它仍然匹配作为电子邮件一部分的 url。

来自 email@example.com 的example.com也将被匹配。我试图避免的事情。@被视为非单词字符,因此 \b 将其视为单词边界。

这个问题有没有好的替代解决方案?

编辑:

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

4

2 回答 2

1

当您需要“跳过”某个匹配项并替换另一个匹配项时,通常的“技巧”是匹配并捕获您需要的内容并匹配您不需要的内容。由于两种上下文的替换模式不同,您应该能够分析匹配对象,并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

在线 Java 演示java.util.regex使用相同的技术)

图案细节

  • \\S+@\\S+\\.\\S+- 匹配类似于电子邮件的内容(1+ 个非空格、@、1+ 个非空格,.以及 1+ 个非空格)
  • |- 或者
  • ((?:https?://)?(?:[a-z0-9-]+[.])*[a-z0-9-]+[.][a-z]+/?[^\\s() <>]*)- 第 1 组捕捉您的模式。

如果 Group 1 匹配,则不是null,我们需要将其包装到标签中。否则,只需重新插入整个匹配项。

于 2016-12-08T10:49:28.423 回答
0

对于 email@example.com 正则表达式将简单地将 e 匹配为 [^@] 并将 xample.com 匹配为匹配的其余部分 - 它们稍后将合并为一个匹配项。只需检查 URL 之前的空格,但不要将其包含在子模式中。

看看,这可以帮助你。preg_match_all 查找所有 URL 但不包括电子邮件

于 2016-12-08T07:42:15.797 回答