为什么[[a-z] *&& [^ a]]没有“bc”,而是“b”?

时间:2016-02-14 08:36:46

标签: java regex

好的,所以我试图更熟悉正则表达式中的交集(&&)。 在java.util.Pattern页面上解释了所有正则表达式,&&仅在范围旁边使用(例如[a-z&&[^e]])。但我尝试使用它:[[a-z]*&&[^a]]。对我而言,这似乎是合乎逻辑的,这将匹配所有小写字符串,期望字符串"a",但它似乎与[a-z&&[^a]]等效。

所以实际问题是*运营商去了哪里?这怎么只捕获单个字符串?

4 个答案:

答案 0 :(得分:2)

我认为您使用交叉点的方法是错误的:要匹配除"a"以外的所有小写字符串:

^(?!a$)[a-z]+$

您可以在致电^时放弃包裹$matches()

if (input.matches("(?!a$)[a-z]+")) {
    // it's an all-lowercase string, but not "a"
}

当然你不需要正则表达式。虽然它有点啰嗦:

if (input.equals(input.toLowerCase()) && !input.equals("a"))

但您可以更轻松地阅读。

答案 1 :(得分:1)

字符类(由[]标记)内,*字符没有特殊含义。它只是代表角色本身。

所以正则表达式

[[a-z]*&&[^a]]

只允许一个字符为以下字符之一:

b, c, d, ..., z, *

[a-z]和以下*已合并,生成的字符类与[^a]相交,只会删除a字符。

有效字符串是(例如):

b
*
c

但是

a

不是,以及包含多个字符的每个字符串。

现在找到你想要的解决方案。你想要有字符串(允许多个字符,我假设)也可以包含字母'a'但不包含字符串“a”。最简单的是一个做出这种区分的小组:

(?!a$)[a-z]*

(?!a$)称为零宽度负向前瞻。这意味着查看的字符不被消耗(零宽度),并且不允许(否定)。 '$'字符一直持续到最后。否则,以'a'开头的单词也将被拒绝。

答案 2 :(得分:0)

Java中支持字符类交集 。问题是在角色类中,*失去了它的特殊含义,文字明星" *"将被匹配。你的正则表达式应该是:

[a-z&&[^a]]*

现在它将匹配范围内的所有字符" a-z"除了" a"字符。

示例:

Pattern p = Pattern.compile("[a-z&&[^a]]");
Matcher m = p.matcher("a");
System.out.println(m.matches()); // false

答案 3 :(得分:0)

尝试在课堂外使用*

[[a-z]&&[^a]]*

截取两个字符类会为您提供另一个字符类。 正如在其他答案中所说,*并不意味着课堂内的数量。所以,在外面使用它。

相关问题