我们经常会需要编写代码来验证用户输入,比如输入是否是一个数字,是否是一个邮箱等等。编写这类代码一个简单有效的做法就是使用正则表达式。
正则表达式是一个字符串,用来描述匹配一个字符串集合的模式。我们可以使用正则表达式来匹配、替换和分割字符串。
匹配字符串
先说一下String类中matchs方法:乍一看,matches方法很像equals方法。
"Test".matches("Test"); //True
"Test".equals("Test"); //True
这两个方法返回的结果都是True,但是matches方法其实更强大。它不仅可以匹配上述代码固定的字符串,还可以匹配一个模式的字符串。
"Test True or False".matches("Test.*") //True
"Test False or True".matches("Test.*") //True
上述代码的“Test.*”就是一个正则表达式。它描述了一个字符串的模式:从Test开始,后面跟任意字符串。.*匹配的是任意0或多个字符。
正则表达式语法
正则表达式由字符和特殊符号构成。反斜杠是特殊字符(转义符),因此使用\d来表示\d(两次转义)。
正则表达式 | 匹配 | 示例 |
---|---|---|
x | 指定字符x | test->test |
. | 任意单个字符 | test->t…t |
(ab|cd) | ab或cd | asd->a(sd|qeicbn) |
[abc] | a或b或c | test->te[asdf]t |
[^abc] | 除a或b或c以外的任何字符 | test->te[^qwe]t |
[a-z] | a到z的任何字符 | test->t[a-z]st |
[^a-z] | 除a到z以外的任何字符 | test->tes[^a-s] |
[a-e[m-p]] | a到e或m到p | Test->[F-U[I-M]]es[f-u] |
[a-e&&[c-p]] | a到e和c到p | Test->[A-O&&[R-Z]]es[a-z] |
\d | 一位数,同[0-9] | test1->test[\\d] |
\D | 一位非数字 | test->[\\D]est |
\w | 单词字符 | test->[\\w]es[\\w] |
\W | 非单词字符 | test1->test[\\W] |
\s | 空白字符 | tes t->tes\\st |
\S | 非空白字符 | tes t->[\\S]es t |
p* | p任意次出现 | tttest->t*est ~ testtesttest->(test)* |
p+ | p至少出现一次 | e->e+t* ~ test->(te)+.* |
p? | p至多出现一次 | test->t?est |
p{n} | p恰好出现n次 | test->t{1}e.* |
p{n, } | p至少出现n次 | tttt->t{1,} |
p{n,m} | p出现n到m次 | tttt->t{1,5} |
- 单词字符是所有字母,数字和下划线。\w等同[a-z[A-Z][0-9]_]。\W等同于[^a-Za-z0-9]
- p{n,}和p{n,m}中不能有空格,
A{3, 6}(逗号和6有空格) - 可以使用小括号()来给模式分组,比如(ab)3->ababab,但是ab{3}->abbb
举个例子:QQ号的匹配是[1-9][0-9]{4,}。分析:qq号开头不能是0吧?所以[1-9]的意思是第一位为1到9的个位数,[0-9]{4,}的意思是剩下的是0到9的数字,但是至少有4位(qq号最少5位,此处4位+第一个1位)。
另外,有在线匹配正则表达式的网站,比如这个。可以测试你的正则表达式是否匹配,另外还有一些常用的正则表达式例子。
替换和分割字符串
使用String类的matches方法匹配正则表达式,如果能匹配那么返回true,反之为false。String类还包括repalceAll,replaceFirst,split方法,可以使用这些方法来替换和分割字符串。
System.out.println("Test Test Test".replaceAll("s\\w", "ok")); //Teok Teok Teok
System.out.println("Test Test Test".replaceFirst("s\\w", "ok")); //Teok Test Test
String[] test = "Test1test2TEST".split("\\d");
for(String t : test){
System.out.println(t);
} //Test test TEST
split方法后跟第二个参数(split(字符串, 匹配次数))用于确定模式匹配多少次。
另外,量词符默认都是贪婪的,就是说,如果要多次匹配(具体次数没有指定),那么默认是匹配最多次。可以再量词符后加?来使它变成匹配最少次。比如
System.out.println("Teeestt".replaceFirst("e+", "O")); //Tostt
System.out.println("Teeestt".replaceFirst("e+?", "o")); //Toeestt
最后:正则表达式是一个很有用的工具,要熟练掌握还需要多加练习。