[英]Why does my negative lookbehind not work in Java?
I am attempting to use negative lookbehind to do some matching on strings that will get sent into the system from another system that ours talks to. 我试图使用负向lookbehind来对字符串进行一些匹配,这些字符串将从我们所讨论的另一个系统发送到系统中。 I have searched for similar questions and I have not been able to solve this based on any previously posted questions. 我搜索过类似的问题,但我无法根据之前发布的任何问题解决此问题。
This works as expected 这按预期工作
Pattern pattern = Pattern.compile ("^(?<!SyCs-)([A-Za-z\\s\\d]+)$");
String s = "SyCs-a";
Assert.assertEquals (false, pattern.matcher (s).matches ());
Here's the problem: with the current regex, the following also returns false which makes sense because the '-' (dash) is not part of the allowed values ([A-Za-z\\s\\d]+) . 这是问题:对于当前正则表达式,以下也返回false,这是有道理的,因为' - '(破折号)不是允许值的一部分([A-Za-z \\ s \\ d] +) 。
s = "TyCs-a";
Assert.assertEquals (false, pattern.matcher (s).matches ());
However, I need that to return true but when I add the dash to allowed values, the first String returns true as well. 但是,我需要返回true,但是当我将破折号添加到允许值时,第一个String也返回true。
No dash 没有冲刺
Pattern pattern = Pattern.compile ("^(?<!SyCs-)([A-Za-z\\s\\d]+)$");
String s = "SyCs-a";
Assert.assertEquals (false, pattern.matcher (s).matches ());
s = "TyCs-a";
Assert.assertEquals (false, pattern.matcher (s).matches ());
With dash 用破折号
Pattern pattern = Pattern.compile ("^(?<!SyCs-)([A-Za-z\\s\\d-]+)$");
String s = "SyCs-a";
Assert.assertEquals (true, pattern.matcher (s).matches ());
s = "TyCs-a";
Assert.assertEquals (true, pattern.matcher (s).matches ());
I've tried to make the + not greedy +? 我试过让+不贪婪+? but that doesn't change the outcomes at all. 但这根本不会改变结果。
Any suggestions? 有什么建议?
Here's the whole set of tests that I am using to verify the regex 这是我用来验证正则表达式的整套测试
@Test
public void testNegativeLookBehind () {
Pattern pattern = Pattern.compile ("^(?<!SyCs-)([A-Za-z\\s\\d]+)$");
String s = "SyCs-a";
Assert.assertEquals (false, pattern.matcher (s).matches ());
s = "SyCs-b";
Assert.assertEquals (false, pattern.matcher (s).matches ());
s = "SyCs-ab";
Assert.assertEquals (false, pattern.matcher (s).matches ());
s = "SyCs-ab1";
Assert.assertEquals (false, pattern.matcher (s).matches ());
s = "SyCs-abZ";
Assert.assertEquals (false, pattern.matcher (s).matches ());
s = "SyCs- abZ";
Assert.assertEquals (false, pattern.matcher (s).matches ());
s = "SyCs ab1";
Assert.assertEquals (true, pattern.matcher (s).matches ());
/*s = "TyCs-a";
Assert.assertEquals (true, pattern.matcher (s).matches ());
s = "SyCr-a";
Assert.assertEquals (true, pattern.matcher (s).matches ());
*/
s = "ab";
Assert.assertEquals (true, pattern.matcher (s).matches ());
s = "sab";
Assert.assertEquals (true, pattern.matcher (s).matches ());
s = "Csab";
Assert.assertEquals (true, pattern.matcher (s).matches ());
s = "yCsab";
Assert.assertEquals (true, pattern.matcher (s).matches ());
s = "SyCsab";
Assert.assertEquals (true, pattern.matcher (s).matches ());
}
The (?<!SyCs-)
is a negative lookbehind that fails the match if there is CyCs-
immediately to the left of the current location. (?<!SyCs-)
是负面的后视,如果有CyCs-
当前位置的左侧,则CyCs-
匹配失败。 Since the current location is the start of string ( ^
) the lookbehind always returns true and is just useless. 由于当前位置是字符串( ^
)的开头,因此lookbehind 总是返回true并且无用。
You need to use a lookahead here, not a lookbehind: 你需要在这里使用一个前瞻,而不是一个lookbehind:
String pat = "^(?!SyCs-)[A-Za-z\\s\\d-]+$";
^^^^^^^^^
See the regex demo . 请参阅正则表达式演示 。
The ^(?!SyCs-)
will check if the string starts with SyCs-
and if it does, the match will be failed. ^(?!SyCs-)
将检查字符串是否以SyCs-
- 如果是,则匹配将失败。
Note that if you use the pattern with .matches()
method, you may omit ^
and $
anchors in the pattern as that method requires a full string match. 请注意,如果将模式与.matches()
方法一起使用,则可以省略模式中的^
和$
anchors,因为该方法需要完整的字符串匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.