java - ^[A-Z](([A-Z_0-9])*[^_])?$ 错误匹配

标签 java regex regex-negation

需要 Java 泛型类型参数的正则表达式,所以我试过:

^[A-Z](([A-Z_0-9])*[^_])?$

表示类型名称应该有 1 个或多个字符,全部大写和数字,这是可能的
使用'_'作为分隔符,但不是在最后,f.e。 'TT_A9'
但令我惊讶的是,我的正则表达式工具显示了“Aa”或“AAa”或“AA-”的匹配
我写了一个简单的测试类来检查:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegexTestPatternMatcher { 

public static final String test = "AA-";

public static void main(String[] args) {
   Pattern pattern = Pattern.compile("^[A-Z](([A-Z_0-9])*[^_])?$");
   Matcher matcher = pattern.matcher(test);
   System.out.println("Matches ? " + matcher.matches());
  }
}

输出:

AA- Matches ? true

对于AAa也是如此,但对于AA_则不然
如果我使用正则表达式 ^[A-Z](([A-Z_0-9])*[^_a-z-])?$
但我不明白为什么我需要使用 'a-z' 和 '-' 作为排除项,
当我只寻找大写字符时!?

最佳答案

使用 negated character class 时- 与您的原始模式一样,[^_] - 你告诉正则表达式使用类中定义的字符以外的字符。因此,您的正则表达式实际上至少需要 2 个字符,第一个是大写 ASCII 字母,以及除 _ 之外的任何字符。最后,_ 中可以有任何字符, 0-9A-Z介于两者之间。

您正在寻找 negative lookbehind锚定在字符串的末尾:

^[A-Z][A-Z_0-9]*$(?<!_)
                 ^^^^^^

参见 regex demo

所有匹配 _ 的匹配都会失败在字符串的末尾。 _不被消耗,它只被检查是否存在,因此该模式将接受(匹配)一个以大写 ASCII 字母开头的 1 个字符的字符串,并且可以选择后跟 [A-Z_0-9] 中定义的范围内的字符。字符类。

我还建议删除所有冗余分组(无论如何您都不会使用捕获的子文本)。

关于java - ^[A-Z](([A-Z_0-9])*[^_])?$ 错误匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40620155/

相关文章:

javascript - 在 .split() 函数中使用捕获组

java - 从 RPG 调用 iSeries 上的远程 Java 程序

javascript - 正则表达式,用于匹配包含一个单词但不包含另一个单词的URL

regex - 如何在grep中转义方括号内的方括号

jquery - 有效 css 和/或 jQuery 选择器的正则表达式

python - 如何去除unicode字符串中的空格

regex - 打开文件并使用正则表达式对其进行过滤

java - 如何从 Hoover 菜单 Selenium JAVA 打开 WebElement

java - 通用枚举/EnumSet 问题

java - Spring Projections 不返回状态详细信息