字符串只能包含[a-zA-Z0-9_]符号(可以从一个字母开始,但不能包含“ _”),不能从数字开始

时间:2019-09-05 08:17:24

标签: java regex

我正在解决Java中的一个问题,需要制作一个正则表达式,该正则表达式将检查字符串以查找下一条规则:

  1. 字符串必须仅包含数字,大写和小写字母以及下划线字符"_";
  2. 字符串不能以数字开头;
  3. 如果字符串从下划线开始,则第二个字符不能为下划线,即必须为数字或字母;
  4. 字符串只能由一个字符组成,但此字符不能为下划线;

我不明白如何制作正则表达式的第一部分。我试图使其部分化:

  1. 表达式"_[a-zA-Z0-9]"满足以下条件:“如果字符串从下划线字符开始,则第二个字符是字母或数字”。
  2. 表达式"\\D"满足条件“字符串不能从数字开头”。
  3. 表达式"[a-zA-Z]"满足条件“字符串从大写或小写字母开始”。

表达式的最后一部分很简单-"w*"

当我尝试将所有这些放在一起"(_[a-zA-Z0-9])*|(\\D)*|([a-zA-Z])*w*"时,获得的regexp无法正常工作。

以下字符串b33_n1不适合我的正则表达式,但字符串__适合它。

如何修复我的正则表达式?

2 个答案:

答案 0 :(得分:2)

您可以使用

^(?![0-9]|__|_$)[a-zA-Z0-9_]+$

或者,以简写方式:

^(?!\d|__|_$)\w+$

请参见regex demo

详细信息

  • ^-字符串的开头(在.matches()中隐含)
  • (?![0-9]|__|_$)-之后,不能有数字或__子字符串,或_后跟字符串结尾
  • [a-zA-Z0-9_]+-1个以上的ASCII字母,数字或_(也可以使用*来匹配一个空字符串)
  • $-字符串的结尾(在.matches()中隐含)。

在Java中,将其与.matches()一起使用,以省略锚点:

s.matches("(?!\\d|__|_$)\\w+")

答案 1 :(得分:1)

@Wiktor的回答是正确且紧凑的。但是,我想提供一种仅部分使用正则表达式的替代方法。我经常也在网上搜索紧凑的正则表达式,并经常得到答案,但是两个月后我不知道该表达式的含义。

如果您不是WiktorStribiżew这样的正则表达式天才,并且想一眼就看一下已验证的内容,建议您采用以下方法

static boolean check(String s){
    if(s.matches("[a-zA-Z0-9_]+")){
        if( !Character.isDigit(s.charAt(0))){
            if(!s.startsWith("__")){
                return !(s.length() == 1 && s.equals("_"));
            }
        }
    }
    return false;
}