正则表达式

正则表达式

java标准库的java.util.regex包内置了正则表达式引擎。

String类型也支持正则表达式,但不强大。

public class Main{
   public static void main(String[] args) {
       String regex="20\\d\\d"; //d代表数字
       System.out.println("2019".matches(regex));//true
       System.out.println("2100".matches(regex));//false
  }
}

匹配规则

  • 从左到右按规则匹配

  • 对于正则表达式abc来说,只能精确匹配字符串abc

  • 如果含特殊字符,需用\转义,如正则表达式a\\&,只能匹配a&c,java中用a//&b表示。

  • 匹配中文字符,可用\u####的十六进制表示,例如\u548cc匹配字符串a和c,也可以用a和c


模糊匹配

规则 正则表达式 可以匹配
A 指定字符 A
\u548c 指定unicode字符
. 任意一个字符 所有字符
\d 0~9 0~9
\w 字母、数字和下划线 a~z,A~Z,0~9,_
\s 空格、Tab键 空格,Tab
\D 非数字 a,&,....
\W 非\w &,中,......
\S 非\s a,Z,&,......

重复匹配

正则表达式 规则 可以匹配
A* 任意个数字符 空,A,AA,AAA,......
A+ 至少1个字符 A,AA,AAA,......
A? 0或1个字符 空,A
A{3} 指定个数字符 AAA
A{2,3} 指定范围个数字符 AA,AAA
A{2,} 至少n个字符 AA,AAA,.......
A{0,3} 最多n个字符 空,A,AA,AAA

匹配开头和结尾

多行匹配时,^表示开头,$表示结尾,例如^A\d{3}$,可以匹配A001A380


匹配指定范围

使用[...]可以匹配范围内的字符,例如[123456789]可以匹配1~9,或者简写为[1-9][^1-9]{3}表示不包含指定范围的字符。


或规则匹配

|连接的两个正则规则是规则,例如AB|CD可以匹配ABCD


或规则+括号

将公共部分提取出来,子规则用括号括起来。如learn\\s(java|php|go)可以匹配learn java,learn php,learn go


复杂匹配总结

正则表达式 规则 可以匹配
^ 开头 字符串开头
$ 结尾 字符串结束
[ABC] [...]内任意字符 A,B,C
[A-F0-9xy] 指定范围内的字符 A,...,F,...,0,...,9,x,y
[^A-F] 指定范围外的任意字符 A~F
AB|CD|EF AB或CD或EF AB,CD,EF
A(B|C|D) AB或AC或AD AB或AC或AD

分组匹配

必须引入java.util.regex包。

import java.util.regex.*;
public class Main {
   public static void main(String[] args) {
       pattern p=new Pattern.compile("(\\d{3,4})\\-(\\d{7,8})");//括号分组
       Matcher m=p.matcher("010-12345678");
       if(m.matches()){
           String g1=m.group(1);//提取\\d{3,4}部分,0嗲白哦整个正则匹配到的字符串
           String g2=m.group(2);
      }
  }
}

搜索和替换

分割字符串

"a b c".split("\\s"); // { "a", "b", "c" }
"a b c".split("\\s"); // { "a", "b", "", "c" }
"a,b ;; c".split("[\\,\\;\\s]+");//["a","b","c"] //分割

搜素字符串

import java.util.regex.*;
ublic class Main {
   public static void main(String[] args) {
       String s = "the quick brown fox jumps over the lazy dog.";
       Pattern p = Pattern.compile("\\wo\\w");
       Matcher m = p.matcher(s);
       while(m.find()){ //find函数找字串
           String sub=s.substring(m.start(),m.end()); //开始和结束位置
      }
  }
}

在获取Mather对象后,不需要调用matches()方法(匹配整个串肯定返回false),而是反复调用find()方法,在整个串中搜索能匹配\\wo\\w规则的字串。


替换字符串

public class Main {
   public static void main(String[] args) {
       String s = "The     quick\t\t brown   fox jumps   over the lazy dog.";
       String r=s.replaceAll("\\s+"," ");
       System.out.println(r); // "The quick brown fox jumps over the lazy dog."
       String r2=s.replaceAll("\\s([a-z]{4}\\s)"," <b>$1</b> " );  //用匹配的分组子串([a-z]{4})替换了$1
       System.out.println(r2);
  }
}

非贪婪匹配

import java.util.regex.*;
public class Main {
   public static void main(String[] args) {
       Pattern pattern = Pattern.compile("(\\d+?)(0*)");//?表示非贪婪匹配
       Matcher matcher = pattern.matcher("1230000");
       if (matcher.matches()) {
           System.out.println("group1=" + matcher.group(1)); // "123"
           System.out.println("group2=" + matcher.group(2)); // "0000"
      }
  }
}

(\d??)(9*),\d?表示匹配0个或1个数组,后面第二个?表示非贪婪匹配。^()?都有双义。

上一篇:C# 去掉Windows不能用于文件名的字符


下一篇:如何正确书写正则表达式