Java进阶(六)正则匹配
单字符匹配
字符 | 作用 | 描述 |
. | 任意字符匹配 \. 匹配除换行符 \n 之外的任何单字符 | 例如a.c可以匹配"abc",但不能匹配"ac"、"a&&c" |
s | 空格字符匹配 \s 匹配一个空格字符,包括空格、制表符、换页符等等,等价于 [ \f\n\r\t\v] | 例如 a\sc 可以匹配"a c",因为\s可以匹配空格字符,但不能匹配"ac","abc"等. \S可以匹配任何非空白字符 |
d | 数字字符匹配 \d 匹配一个数字 | 例如00\d可以匹配"007",但不能匹配"00A","0077"。\D则匹配一个非数字 |
w | 常用字符匹配 \w 匹配一个字母、数字或下划线,w的意思是word | 例如java\w可以匹配"javac","java9"等,但不能匹配"java#" |
重复匹配
字符 | 作用 | 描述 |
* | 匹配前面的子表达式零次或多次 | 例如zo* 能匹配 "z" 以及 "zoo"。* 等价于{0,} |
+ | 匹配前面的子表达式一次或多次 | 例如'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,} |
? | 匹配前面的子表达式零次或一次 | 例如"do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 、 "doxy" 中的 "do" 。? 等价于 {0,1} |
{n} | 匹配确定的 n 次 | 例如'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o |
{n,} | 至少匹配n 次 | 例如'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*' |
{n,m} | 最少匹配 n 次且最多匹配 m 次 | 例如"o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?' |
范围匹配
字符 | 作用 | 描述 |
^ | 匹配输入字符串的开始位置 | 例如^A\d{3}$,可以匹配"A001"、"A380" |
$ | 匹配输入字符串的结尾位置 | |
\b | 匹配一个单词边界,即字与空格间的位置。 | 例如,"er\b"匹配"never"中的"er",但不匹配"verb"中的"er" |
[...] | 匹配[]中指定范围内的字符 | 例如一个7~8位数字的电话号码,可以用[123456789]\d{6,7}匹配 |
[^...] | 匹配[]中指定范围外的字符 | |
| | 或规则 | 例如,AB|CD表示可以匹配AB或CD |
分组匹配
正则匹配 区号-电话号码 这个规则,可以用(\d{3,4})\-(\d{6,8})
public class RegexTest1 { public static void main(String[] args) { String text = "(\\d{3,4})\\-(\\d{7,8})"; //A compiled representation of a regular expression. Pattern p = Pattern.compile(text); //An engine that performs match operations on a character sequence by interpreting a Pattern. Matcher m = p.matcher("010-12345678"); if (m.matches()) { printGroupInfo(m); } } private static void printGroupInfo(Matcher m) { String g1 = m.group(1); String g2 = m.group(2); System.out.println(g1); System.out.println(g2); } }
非贪婪匹配
正则表达式匹配默认使用贪婪匹配,通过在 *、+ 或 ? 限定符之后放置 ?,该表达式从"贪婪"表达式转换为"非贪婪"表达式或者最小匹配
public class RegexTest1 { public static void main(String[] args) { //因为正则表达式默认使用贪婪匹配:任何一个规则,它总是尽可能多地向后匹配,因此,\d+总是会把后面的0包含进来 Pattern pattern = Pattern.compile("(\\d+)(0*)"); Matcher matcher = pattern.matcher("1230000"); if (matcher.matches()) { System.out.println("group1=" + matcher.group(1)); // "1230000" System.out.println("group2=" + matcher.group(2)); // "" } pattern = Pattern.compile("(\\d+?)(0*)"); matcher = pattern.matcher("1230000"); if (matcher.matches()) { System.out.println("group1=" + matcher.group(1)); // "123" System.out.println("group2=" + matcher.group(2)); // "0000" } } }
搜索字符串
public class RegexTest3 { 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()) { String sub = s.substring(m.start(), m.end()); System.out.println(sub); } } } /* * row fox dog */
替换字符串
public class RegexTest4 { 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." } }
反向引用
反向引用需要使用到分组,分组就是使用()括起来的部分为一个整体,在进行分组匹配时的原则是:由外向内,由左向右。每一组都有一个行号,从1开始。
比如一个文本以abc开始,接着为xyz,紧跟着abc,对应的正则表达式可以为“abcxyzabc”,也可以使用反向引用重写正则表达式,“"(abc)xyz\1"”
public class RegexTest5 { public static void main(String[] args) { 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); } }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步