匹配规则

若正则表达式内有特殊字符,那就需要用\转义,正则表达式a\&c,其中\&是用来匹配特殊字符&的,它能精确匹配字符串"a&c"。在Java中对应正则表达式a\&c的字符串为a\\&c。两个\\实际上表示的是一个\
若想匹配非ASCLL字符,例如匹配中文,那就用\u####的十六进制表示,例如\u548c的Unicode编码是,则a\u548cc匹配字符串”a和c”
精准匹配不常用正则表达式,一般用String.equals()就可以做到。大多数情况下,正则表达式往往用于模糊匹配

匹配任意字符

例如,正则表达式a.c中间的.可以匹配任意一个字符。

匹配数字

.可以匹配任意字符,如果只想匹配0~9这样的单个数字,可以用\d匹配 。

匹配常用字符

\w可以 匹配一个字母、数字或下划线

匹配空格字符

\s可以匹配一个空格字符,注意空格字符不但包含空格,还包括tab字符

匹配非数字

\D匹配一个非数字
以此类推,\W可以匹配\w不能匹配的字符,\S可以匹配\s不能匹配的字符

重复匹配

若要匹配多个数字,比如“A380”,则可以使用修饰符*,它可以匹配任意个字符,包括0个字符
修饰符+表示可以匹配至少一个字符
修饰符?表示可以匹配0个或1个字符,无法匹配超过一个的字符
若要精准匹配指定的n个字符,则可以用修饰符{n}
若要精准匹配指定的n个到m个字符,则可以用修饰符{n,m}

小结

单个字符的匹配规则如下:

| 正则表达式 | 规则 | 可以匹配 | | —- | —- | —- |

| A | 指定字符 | A |

| \u548c | 指定Unicode字符 | |

| . | 任意字符 | ab&0 |

| \d | 数字0~9 | 0~9 |

| \w | 大小写字母,数字和下划线 | a``Z0~9_ |

| \s | 空格、Tab键 | 空格,Tab |

| \D | 非数字 | aA&_,…… |

| \W | 非\w | &@,…… |

| \S | 非\s | aA&_,…… |

多个字符的匹配规则如下:

| 正则表达式 | 规则 | 可以匹配 | | —- | —- | —- |

| A* | 任意个数字符 | 空,AAAAAA,…… |

| A+ | 至少1个字符 | AAAAAA,…… |

| A? | 0个或1个字符 | 空,A |

| A{3} | 指定个数字符 | AAA |

| A{2,3} | 指定范围个数字符 | AAAAA |

| A{2,} | 至少n个字符 | AAAAAAAAA,…… |

| A{0,3} | 最多n个字符 | 空,AAAAAA |

匹配开头和结尾

用正则表达式中,用^表示开头,用$表示结尾。

匹配指定范围

使用[…]可以匹配范围内的字符,、[123456789]可以匹配1~9,把所有字符列出来太麻烦,可以把[123456789]写成[1-9]
同理,[a-zA-F]可以匹配所有大小写英文字符。
[…]的用法还可以排除,即不包含指定范围的字符。例如我们要匹配任意非数字的字符,可以写成[^1-9]

或匹配原则

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

使用括号

现在我们想要匹配字符串learn javalearn phplearn go怎么办?一个最简单的规则是learn\sjava|learn\sphp|learn\sgo,但是这个规则太复杂了,可以把公共部分提出来,然后用(...)把子规则括起来表示成learn\\s(java|php|go)

小结

复杂匹配规则主要有:

| 正则表达式 | 规则 | 可以匹配 | | —- | —- | —- |

| ^ | 开头 | 字符串开头 |

| $ | 结尾 | 字符串结束 |

| [ABC] | […]内任意字符 | A,B,C |

| [A-F0-9xy] | 指定范围的字符 | A,……,F0,……,9xy |

| [^A-F] | 指定范围外的任意字符 | 非A~F |

| AB|CD|EF | AB或CD或EF | ABCDEF |

分组匹配

(…)还有一个作用就是分组匹配,对于用正则匹配区号-电话号这个规则,示例为\d{3,4}\t\d{6,8},在匹配成功后下一步是提取区号和电话号,分别存入数据库,正确的做法就是用(...)将刚才的正则表达式变为(\d{3,4}\t\d{6,8})。如果匹配成功,就可以直接从Matcher.group(index)返回子串。注意如果传入的参数为1表示第一个子串,2为第二个子串,0表示整个匹配到的字符串。

非贪婪匹配原则

正则表达默认的模式为贪婪匹配原则,例如对于"123000"这个字符串,我们期望得到末尾零的个数,故写出正则表达式(\d+)(0*),但实际上的结果为

贪婪匹配即它总是尽可能地往后匹配,要使后面的0*尽可能的多匹配,就必须让\d+使用非贪婪匹配。在规则\d+后面加上?号即表示非贪婪匹配,注意要将\d??\d?区分开,在\d??中,第一个问好表示匹配0个或1个数字,对第二个?表示非贪婪匹配。对于字符串”9999”,使用(\d??)(9*)匹配,结果两个子串为""9999"",非贪婪表示尽可能少的匹配,结果匹配了0个9

分割、搜索和替换

  1. 分割使用String.split("\\s"); `` "a b c".split("\\s");// 结果{"a","b","c"},\ “a b c”.split(“\s”); // { “a”, “b”, “”, “c” } “a, b ;; c”.split(“[\,\;\s]+”); // { “a”, “b”, “c” }
  1. 2. 搜索字符串
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()) {
    String sub = s.substring(m.start(), m.end());
    System.out.println(sub);
}

// result: // row // fox // dog


3. 替换字符串
    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."

4. 反向引用

如果要将匹配到的子串进行处理,比如前后加一个`<b>xxxx</b>`,则可以使用$1,$2来反向引用匹配到的子串
String s = "the quick brown fox jumps over the lazy dog.";
String r = s.replaceAll("\\s([a-z]{4})\\s", " <b>$1</b> ");
System.out.println(r);

`` 结果:the quick brown fox jumps over the lazy dog.`