我正在尝试使用负向后看对字符串进行一些匹配,这些字符串将从与我们交谈的另一个系统发送到系统中。我已经搜索了类似的问题,但根据以前发布的任何问题我都无法解决。

这按预期工作

Pattern pattern = Pattern.compile ("^(?<!SyCs-)([A-Za-z\\s\\d]+)$");
String s = "SyCs-a";

Assert.assertEquals (false, pattern.matcher (s).matches ());

这是问题所在:对于当前的正则表达式,以下内容也会返回false,这是有道理的,因为'-'(破折号)不是允许值([A-Za-z \ s \ d] +)的一部分。
s = "TyCs-a";

Assert.assertEquals (false, pattern.matcher (s).matches ());

但是,我需要返回true,但是当我在允许的值中添加破折号时,第一个String也会返回true。

没有破折号
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 ());

带破折号
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 ());

我试图使+不贪心+?但这根本不会改变结果。

有什么建议?

这是我用来验证正则表达式的整套测试
@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 ());
}

最佳答案

(?<!SyCs-)是一个向后的否定性查询,如果当前位置左侧紧邻CyCs-,则匹配失败。由于当前位置是字符串(^)的开头,因此后向总是返回true,并且是无用的。

您需要在这里使用前瞻性,而不是在后面:

String pat = "^(?!SyCs-)[A-Za-z\\s\\d-]+$";
               ^^^^^^^^^

参见regex demo
^(?!SyCs-)将检查字符串是否以SyCs-开头,如果匹配,则匹配失败。

请注意,如果您将模式与.matches()方法一起使用,则可以在模式中省略^$锚,因为该方法需要完整的字符串匹配。

07-24 06:07