2016-12-08 30 views
0

我正在使用re2/J来提取URL,无论它们是否以正则表达式开始。 我使用的是相当简单的模式,如何使用正则表达式将url作为单词匹配而不使用标准单词边界?

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

但是我加入\ b在开始和结尾是\ B不是帮助我很多。它仍然是匹配电子邮件的一部分的网址。

example.com from email @example.com也会被匹配。我正在努力避免的事情。 @被视为非单词字符,因此\ b将其视为单词边界。

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

编辑:

请注意,我试图替换HTML锚标记网址,所以我没有真正寻找匹配。我必须指定一个模式和一个替换捕获的组。

+0

在re2中不支持lookarounds,唯一的解决方法是* match *你不需要和* capture *你需要的东西。见['(?i)\ S + @ \ S +。\ S + |((?:https:://)?(?:[a-z0-9-] + [。])* [a-z0-9 - ] + [] [AZ] +/[^ \ S()<>] *)'](https://regex101.com/r/5QpPux/1)。?。 –

+0

@WiktorStribiżew您能否详细说明捕捉。检查我的编辑。 –

+0

我不知道're2'是否允许在正则表达式替换方法中使用回调方法。普通的Java正则表达式可以用'Matcher#appendReplacement'来实现。 –

回答

0

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

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

+1

如果'@@ example.com'应该被提取?或者在字符串的开头有一个URL? –

0

当你需要“跳过”一些匹配并替换另一匹配的通常“技巧”是匹配和捕获你需要什么,只是匹配你不需要的东西。由于置换方式的两种情况下的不同,你应该能够分析匹配对象,Matcher#appendReplacement提供了此功能:

String s = "[email protected]\ndomain.com\nwww.domain.com\nhttp://www.domain.com\nhttps://www.domain.com"; 
StringBuffer result = new StringBuffer(); 
Matcher m = Pattern.compile("(?i)\\[email protected]\\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

图案的详细资料

  • \\[email protected]\\S+\\.\\S+ - 匹配的东西,就像一个电子邮件(1+非空格,@,1+非空格,.,再次1+非空格)
  • | - 或
  • ((?:https?://)?(?:[a-z0-9-]+[.])*[a-z0-9-]+[.][a-z]+/?[^\\s() <>]*) - 第1组捕捉你的格局。

如果第1组匹配,它不是null,我们需要将它包装到标签中。否则,只要重新插入整个比赛。

相关问题