如何搜索某些不属于网址的文本?

时间:2016-05-05 12:48:46

标签: regex regex-lookarounds

假设要搜索的文字是pqr

"http://abc.zzz/pqr/xyz"      -> Should not match
"/pqr/"                       -> Should Match
"pqr"                         -> Should Match
"http://abc.zzz/pqr/pqr/"     -> Should not match
"http://abc.zzz/pqr/pqr/ pqr" -> Should match the last "pqr"
"www.pqr.zzz"                 -> Should not match

我尝试使用以下正则表达式

((?:(?:(?:https?|ftp|file|mailto):)|www)[^ ]+?)?(pqr)

然后我找了group 1,如果它是空的那么我认为它是一个匹配。但是http://abc.zzz/pqr/pqr/

失败了

这里有任何帮助来检测匹配的文本是否不是网址的一部分?

我认为最糟糕的情况是首先检测所有网址,然后存储匹配网址的开始和结束索引。然后尝试匹配pqr并排除所有属于网址的人。我在想是否可以做得更好。

1 个答案:

答案 0 :(得分:2)

考虑到您使用的是Java,您可以利用Java正则表达式引擎支持的约束宽度lookbehind 。这意味着您可以在模式中使用{n,m}限制量词。现在,Java 8 supports even * and + quantifiers inside a lookbehind(虽然是非正式的),但这是一个错误,可能会在下一个版本中修复。因此,您可以使用某个范围,例如0 to 1000(因为链接不太可能包含超过1K的符号,但您可以根据实际情况进行调整):

 (?<!(?:(?:https?|ftp|file)://|mailto:)(?:www\.)?\S{0,1000})(?<!\bwww\.\S{0,1000})pqr

请参阅regex demo

第一个lookbehind (?<!(?:(?:https?|ftp|file)://|mailto:)(?:www\.)?\S{0,1000})将检查pqr前面是否没有完整的网址,(?<!\bwww\.\S{0,1000}) lookbehind将检查pqr是否前面没有{{ 1}}。