Java 正则表达式:负前瞻
Posted
技术标签:
【中文标题】Java 正则表达式:负前瞻【英文标题】:Java regex: Negative lookahead 【发布时间】:2012-06-22 22:30:49 【问题描述】:我正在尝试制作两个匹配 URI 的正则表达式。这些 URI 的格式为:/foo/someVariableData
和 /foo/someVariableData/bar/someOtherVariableData
我需要两个正则表达式。每个都需要匹配一个而不是另一个。
我最初想出的正则表达式是:
分别为/foo/.+
和/foo/.+/bar/.+
。
我认为第二个正则表达式很好。它只会匹配第二个字符串。然而,第一个正则表达式匹配两者。所以,我开始(第一次)用消极的前瞻来玩。我设计了正则表达式/foo/.+(?!bar)
并设置了以下代码来测试它
public static void main(String[] args)
String shouldWork = "/foo/abc123doremi";
String shouldntWork = "/foo/abc123doremi/bar/def456fasola";
String regex = "/foo/.+(?!bar)";
System.out.println("ShouldWork: " + shouldWork.matches(regex));
System.out.println("ShouldntWork: " + shouldntWork.matches(regex));
当然,它们都解析为true
。
有人知道我做错了什么吗?我不一定需要使用 Negative lookahead,我只需要解决问题,并且我认为 Negative lookahead 可能是一种方法。
谢谢,
【问题讨论】:
【参考方案1】:试试
String regex = "/foo/(?!.*bar).+";
或者可能
String regex = "/foo/(?!.*\\bbar\\b).+";
为了避免像 /foo/baz/crowbars
这样的路径出现故障,我假设您确实希望该正则表达式匹配。
解释:(没有Java字符串所需的双反斜杠)
/foo/ # Match "/foo/"
(?! # Assert that it's impossible to match the following regex here:
.* # any number of characters
\b # followed by a word boundary
bar # followed by "bar"
\b # followed by a word boundary.
) # End of lookahead assertion
.+ # Match one or more characters
\b
,“单词边界锚点”,匹配字母数字字符和非字母数字字符之间的空格(或字符串的开头/结尾和 alnum 字符之间)。因此,在"bar"
中的b
之前或r
之后匹配,但在"crowbar"
中的w
和b
之间匹配失败。
Protip:看看http://www.regular-expressions.info - 一个很棒的正则表达式教程。
【讨论】:
.*
inside 否定前瞻表达式:(?!.*bar)
是这里的关键,而不是外部:.*(?!bar)
。谢谢。以上是关于Java 正则表达式:负前瞻的主要内容,如果未能解决你的问题,请参考以下文章
正则表达式前瞻(?=)后顾(?<)负前缀(?!)负后顾(?<!)