我正在编写一个正则表达式,用于练习的简单用户名验证。虽然我确信这种模式可能存在其他问题,但如果有人能够解释这种看似奇怪的行为,我希望如此。
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class userRegex{
public static void main(String[] args){
Scanner in = new Scanner(System.in);
int testCases = Integer.parseInt(in.nextLine());
while(testCases>0){
String username = in.nextLine();
String pattern = "([[:alpha:]])[a-zA-Z_]{7,29}";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(username);
if (m.find( )) {
System.out.println("Valid");
} else {
System.out.println("Invalid");
}
testCases--;
}
}
}
当我输入时:
2
dfhidbuffon
dfdidbuffon
编译器应返回:
Valid
Valid
但相反,它会返回
Valid
Invalid
为什么它区分第三个字母的差异" h"或" d"在每个用户名中?
编辑:添加@Draco18s和@ruakh的建议,但是,我仍然得到同样的奇怪行为。
答案 0 :(得分:7)
[:alpha:]
没有您想要的特殊含义;相反,它最终只是意味着"任何字符:
,a
,h
,l
,p
"。因此dfhidbuffon
包含您的模式匹配(即h
加idbuffon
),而dfdidbuffon
则不包含。 (请注意,matcher.find()
会在字符串中查找匹配;如果要专门匹配整个字符串,则应使用matcher.matches()
,或者您可以修改模式以使用^
和$
等锚点。)
您可能会想到许多正则表达式实现中的符号,其中[:alpha:]
表示"任何字母字符&#34 ;;但首先,Java的Pattern
课程并不支持这种表示法(将ajb标记为提示),其次,这些语言需要[:alpha:]
在里面出现一个字符类,例如为[[:alpha:]]
。如果您只想匹配ASCII字母,则Java等效项为\p{Alpha}
或[A-Za-z]
;如果要匹配任何Unicode字母,则为\p{IsAlphabetic}
。
答案 1 :(得分:1)
:Alpha:是字母字符的Posix字符类的简写。
根据Java 7 "Pattern" docs,使用\p{Alpha}
格式支持Posix字符类,而不是:alpha:格式 - 后一种格式未在参考文献中的任何位置列出。
对于我来说,使用支持的Posix字符类定义格式的模式定义可以正常工作,如下所示:
String pattern = "(\\p{Alpha})[a-zA-Z_]{7,29}";
答案 2 :(得分:0)
根据Regexpal.com“([:alpha:])”匹配“任何字符”:','a','h','l','p'“。 “dfdidbuffon”确实包含任何这些字符,因此它失败(永远不会到达[A-z]部分)。
您可能打算"[a-zA-Z](\\w){7,28}"
如果直接使用正则表达式,/[a-zA-Z](\w){7,28}/
这会匹配任何'alpha'字符,然后是7到28个字符(字母数字+下划线)
如果您不想要数字,请"[a-zA-Z]([a-zA-Z_]){7,28}"