(13)正则表达式
正则表达式:其实一种规则,有自己特殊的应用,其作用就是针对于字符串进行操作。
正则:就是用于操作字符串的规则,其中这些规则使用了一些字符表示。
1正则表达式的符号
预定义字符类
. |
任何字符(与行结束符可能匹配也可能不匹配) |
|
\d |
数字:[0-9] |
|
\D |
非数字: [^0-9] |
|
\s |
空白字符:[ \t\n\x0B\f\r] |
|
\S |
非空白字符:[^\s] |
|
\w |
单词字符:[a-zA-Z_0-9] |
|
\W |
非单词字符:[^\w] |
|
System.out.println("a".matches(".")); System.out.println("1".matches("\\d")); System.out.println("%".matches("\\D")); System.out.println("\r".matches("\\s")); System.out.println("^".matches("\\S")); System.out.println("a".matches("\\w")); |
Greedy 数量词
X? |
X,一次或一次也没有 |
X* |
X,零次或多次 |
X+ |
X,一次或多次 |
X{n} |
X,恰好n次 |
X{n,} |
X,至少n次 |
X{n,m} |
X,至少n次,但是不超过m次 |
System.out.println( "a".matches(".") ); System.out.println( "a".matches("a") ); System.out.println("a".matches("a?") ); System.out.println( "aaa".matches("a*") ); System.out.println( "".matches("a+") ); System.out.println( "aaaaa".matches("a{5}") ); System.out.println( "aaaaaaaaa".matches("a{5,8}") ); System.out.println( "aaa".matches("a{5,}") ); System.out.println( "aaaaab".matches("a{5,}") ); |
范围表示
[abc] |
a、b 或 c(简单类) |
[^abc] |
任何字符,除了 a、b 或 c(否定) |
[a-zA-Z] |
a 到 z 或 A 到 Z,两头的字母包括在内(范围) |
[a-d[m-p]] |
a 到 d 或 m 到 p:[a-dm-p](并集) |
[a-z&&[def]] |
d、e 或 f(交集) |
[a-z&&[^bc]] |
a 到 z,除了 b 和 c:[ad-z](减去) |
[a-z&&[^m-p]] |
a 到 z,而非 m 到 p:[a-lq-z](减去) |
|
|
System.out.println( "a".matches("[a]") ); System.out.println( "aa".matches("[a]+") ); System.out.println( "abc".matches("[abc]{3,}") ); System.out.println( "abc".matches("[abc]+") ); System.out.println( "dshfshfu1".matches("[^abc]+") ); System.out.println( "abcdsaA".matches("[a-z]{5,}") ); System.out.println( "abcdsaA12".matches("[a-zA-Z]{5,}") ); System.out.println( "abcdsaA12".matches("[a-zA-Z0-9]{5,}") ); System.out.println( "abdxyz".matches("[a-c[x-z]]+")); System.out.println( "bcbcbc".matches("[a-z&&[b-c]]{5,}")); System.out.println( "tretrt".matches("[a-z&&[^b-c]]{5,}")); |
2 匹配功能
需求:校验QQ号,要求:必须是5~15位数字,0不能开头。没有正则表达式之前
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public static void checkQQ(String qq) 2 { 3 int len = qq.length(); 4 if(len>=5 && len <=15) 5 { 6 if(!qq.startsWith("0")) 7 { 8 try 9 { 10 long l = Long.parseLong(qq); 11 System.out.println("qq:"+l); 12 } 13 catch (NumberFormatException e) 14 { 15 System.out.println("出现非法字符"); 16 } 17 } 18 else 19 System.out.println("不可以0开头"); 20 } 21 else 22 System.out.println("QQ号长度错误"); 23 }
有了正则表达式之后:
[1-9][0-9]{4,14} [1-9]表示是第一位数字是会出现1-9范围之间的其中一个,下来的数字范围会出现在0-9之间,至少出现4次,最多出现14次。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
public static void checkQQ2() { String qq = "12345"; String reg = "[1-9][0-9]{4,14}"; boolean b = qq.matches(reg); System.out.println("b="+b); }
3切割功能
需求1:根据空格对一段字符串进行切割。
1 public static void splitDemo() 2 { 3 String str = "aa.bb.cc"; 4 str = "-1 99 4 23"; 5 String[] arr = str.split(" +"); 6 for(String s : arr) 7 { 8 System.out.println(s); 9 } 10 }
需求2 :根据重叠词进行切割。
1 public static void splitDemo2() 2 { 3 String str = "sdqqfgkkkhjppppkl"; 4 String[] arr = str.split("(.)\\1+"); 5 for(String s : arr) 6 { 7 System.out.println(s); 8 } 9 10 }
注意:为了提高规则复用,用()进行封装,每一个括号都有一个编号,从1开始,为了复用这个规则。可以通过编号来完成该规则的调用。需要对编号数字进行转义。\\1就代表获取1组规则。
4 替换功能
需求:把手机号替换成“*”号。
1 String str = "联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119联系我:13567012119"; 2 String reg= "1[34578]\\d{9}"; 3 str = str.replaceAll(reg,"******"); 4 System.out.println("替换后的帖子:"+ str);
练习二:我我....我...我.要...要要...要学....学学..学.编..编编.编.程.程.程..程
将字符串还原成 我要学编程。
思路先将字符串中的...去掉,然后在把叠词编程一个字
1 String str = "我我....我....我....要....要要....要学....学学....学....编....编编....编.程.程.程.程"; 2 3 str = str.replaceAll("\\.+", ""); // 先把.替换掉 4 System.out.println(str); 5 str = str.replaceAll("(.)\\1+", "$1"); // 要在replaceAll正则的外部引用分组的内容,这时候需要"$组号" 6 System.out.println(str);
5查找功能 正则对象 Pattern 和Match对象
查找需要使用的对象:
1、Pattern类正则对象
1、Matches类匹配器对象
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
因此,典型的调用顺序是
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
步骤:
1,先将正则表达式编译成正则对象。使用的是Pattern类一个静态的方法。compile(regex);
2,让正则对象和要操作的字符串相关联,通过matcher方法完成,并返回匹配器对象。
3,通过匹配器对象的方法将正则模式作用到字符串上对字符串进行针对性的功能操作
注意最终匹配的状态(包括匹配的结果)都驻留在匹配器中,我们要取结果的话,就要到匹配器中来取。
匹配器中常用的方法:
1、find() 通知匹配器取匹配字符串,查找符合规则的字符串。如果能查找到符合规则的字符串返回true,否则返回false
2、group()获取符合规则的字串。
注意使用group()方法的时候,一定要先调用find()方法。
需求:获取由3个字母组成的单词。
1 String content = "da jia de jia qi wan bi liao hai kai xin ma"; 2 String reg = "\\b[a-zA-Z]{3}\\b";// \\b表示单词定界符,两个\\b之间包围的表示一个单词 3 Pattern p = Pattern.compile(reg); 4 Matcher m = p.matcher(content);//最终匹配的结果都在 匹配器中 也就到匹配器中 取结果 5 while(m.find()) //取出所有的结果 内部相当于维护了一个 iterator的指针 6 System.out.println("获取结果:"+m.group());
//邮箱 1373779753@qq.com 邮箱校验功能
1 public static void main(String[] args) 2 { 3 String reg = "[a-zA-Z1-9]\\w{5,17}@[a-zA-Z0-9]{2,}(\\.(com|cn|net|edu)){1,2}"; //注意或运算 4 String str = "下面都是我的邮箱1373779753@qq.com收到货覅15155645365@163.com 还有1000400014@edu.cn"; 5 6 //把字符串编译成正则对象 7 Pattern p = Pattern.compile(reg); 8 //用正则表达式 产生匹配器对象 9 Matcher m = p.matcher(str); 10 while(m.find()) 11 { 12 System.out.println(m.group()); 13 } 14 }