1.8 正则表达式
它的作用是以简洁的形式描述一个字符串是否符合特定格式。一般大家讲到这块,就会列个表,然而一般列表的我都不怎么看(不知道为啥会失去兴趣),给几个常用的用法:
自己匹配自己
Aa 和 Aa 是匹配的
方括号标识单个字符的范围
可以直接罗列 [abcde] 表示,一个字母,a/b/c/d/e 是匹配的其他不匹配
可以用横线描述范围[a-zA-Z]标识所有英文字母中的任意一个
问号 ? 表示匹配 0 到 1 次,星号 * 表示匹配 1 到多次
[a-z]? 表示 1个或0个小写英文字母,匹配项: "a" ""
[a-z]+ 表示 1 次或多次匹配小写英文字母,匹配项:"a", "abcwfw"
指定次数的大括号
{a,b} 表示前面的字符出现 a-b次
{a,} 表示前面字符出现 a 次以上
{,b}表示前面字母出现b次以下
{a} 表示前面字母刚好出现 a 次
边界
^ 开头(也可表示非 [^0-9] 表示非数字)
$ 结尾
字符
统一规则都是小写匹配大写不匹配
\d 意思是 digit 也就是匹配数字,和 [0-9] 一个意思
\D 意思是 非数字,和 [^0-9] 一样
\w 和 \W 一个是字符[a-zA-Z0-9_],一个非字符
\s 或 \S space 也就是空格, \S 是非空格
示例:
11位手机号 ^[\d]{11}$
邮箱 ^([\w]+)[@]{1}([\w]+)\.com$
Java 正则写法:
Pattern pattern = Pattern.compile("正则串");
Matcher matcher = pattern.matcher("尝试匹配串");
if(matcher.matches()){}//配上了,处理
作者示例:
❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤
import java.util.*;
import java.util.regex.*;
public class RegExTest {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Enter pattern: ");
String patternString = in.nextLine();
Pattern pattern = null;
try{
pattern = Pattern.compile(patternString);
}catch (PatternSyntaxException e){
System.out.println("Pattern syntax error");
System.exit(1);
e.printStackTrace();
}
while(true){
System.out.println("Enter string to match:");
String input = in.nextLine();
if(input == null || input.equals("")) return;
Matcher matcher = pattern.matcher(input);
if(matcher.matches()){
System.out.println("Match");
int g = matcher.groupCount();
if(g > 0){
for(int i = 0; i < input.length(); i++){
for(int j = 1; j <= g; j++){
if(i == matcher.start(j))
System.out.print('(');
}
System.out.print(input.charAt(i));
for(int j = 1; j <= g; j++){
if(i + 1 == matcher.end(j)){
System.out.print(')');
}
}
}
System.out.println();
}
}else{
System.out.println("No match");
}
}
}
}
❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤
运行结果:
🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍
^[\d]{11}$
^([\w]+)[@]{1}([\w]+)\.com$
🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍
本人喜欢用正则的地方是空格处理:
❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤
import java.util.*;
public class RegExTest {
public static void main(String[] args) {
String str = "I like write code.";
String rp = str.replaceAll("\\s+"," ");
System.out.println(rp);
String[] word = str.split("\\s+");
System.out.println(Arrays.toString(word));
}
}
❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤
运行结果:
🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍
🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍
正则比较耗内存,对于复杂匹配,它的运行速度也有限,测试如下:
❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤
public class RegExTest {
public static void main(String[] args) {
String[] strs = new String[]{"a@1.com","bwwefwef!@","fwefw@sfwef@","hello@wefw.com","@fewgweg_t.com"};
long start = System.currentTimeMillis();
for(String str:strs){
System.out.println(match1(str));
}
long end = System.currentTimeMillis();
System.out.println(end-start);
start = System.currentTimeMillis();
for(String str:strs){
System.out.println(match2(str));
}
end = System.currentTimeMillis();
System.out.println(end-start);
}
private static boolean match1(String str){
if(str == null) return false;
Pattern pattern = null;
try{
pattern = Pattern.compile("^([\\w]+)[@]{1}([\\w]+)\\.com$");
}catch (PatternSyntaxException e){
System.out.println("Pattern syntax error");
System.exit(1);
e.printStackTrace();
}
Matcher matcher = pattern.matcher(str);
return matcher.matches();
}
private static boolean match2(String str){
if(str == null) return false;
int n =str.length();
//邮箱特点:以 .com 结尾
if(!str.endsWith(".com")) return false;
//邮箱特点: 有 @ 且只有1次,不在开头末尾(非.com末尾)
if(str.indexOf('@')==-1 || str.indexOf('@')==0 || str.indexOf('@')==n-5 || str.indexOf('@')!=str.lastIndexOf('@')) return false;
for(int i = 0; i < n-4; i++){
char c = str.charAt(i);
//其他必须是字母数字下划线
if(!Character.isDigit(c) && !Character.isLetter(c) && c != '_' && c != '@')
return false;
}
return true;
}
}
❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤
运行结果:
🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍
🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍
短短的几条数据,自己匹配和正则差距已经比较大,追求性能,或者一次需要做大量匹配串的情况,最好还是自己写。