前一段时间在网上碰到一道题,要求进行用户名检查:
- 用户名长度要求最短6字符,最长16字符;
- 用户名可以由字母、数字和可选的一个连字号(-)组成;
- 用户名首字符必须为字母,末字符不可以是连字号。
这道题属于送分题,很容易写出下面的Java代码:
public class Username {
public static int MIN_LEN = 6;
public static int MAX_LEN = 16;
public static boolean validate(String username) {
if(username==null ||
username.length()<MIN_LEN ||
username.length()>MAX_LEN ||
!Character.isLetter(username.charAt(0)))
return false;
int hyphenNum = 0;
for(int i=1;i<username.length();i++) {
char ch = username.charAt(i);
if (!Character.isLetterOrDigit(ch)) {
if (ch=='-') {
if(i== username.length()-1 || ++hyphenNum>1) return false;
} else return false;
}
}
return true;
}
public static void main(String[] args) {
String[] tests = new String[] {
null,
"mryqu123",
"mryqu-123",
"mryqu 123",
"mryqu123-",
"mryqu-123-bj",
"123mryqu",
"MryQu-123"
};
for(String test:tests) {
System.out.println(test+","+validate(test));
}
}
}
跟一老友聊天,老友觉得还是用正则表达式代码少,高大上。好吧,添一个方法即可:
public static boolean validateByRegex(String username) {
return username!=null &&
username.matches("(?=^[A-Za-z].*$)(?!^.*\\-$)(?!^.*\\-.*\\-.*$)^[A-Za-z\\d\\-]{6,16}$");
}
最后买一送一,送个JS版的:
这个正则分四部分:
- 使用正向肯定预查匹配字母开始的用户名;
- 使用正向否定预查匹配非连字符结尾的用户名;
- 使用正向否定预查匹配最多含一个连字符的用户名;
- 匹配字母、数字和连字号组成的最短6字符、最长16字符的用户名。