正则表达式笔记
正则表达式
1、匹配符号
正则的 \ 在 java z中要写两个 \。下面均为java 中用法。
-
例子:匹配电话号码:
String re = "0\\d{2,3}-[1-9]\\d{6,7}"; s.matches(re);
2、简单匹配规则
| 符号 | 说明 | 用法 |
|---|---|---|
| \\u548c | 匹配Unicode码 | 中文字符 |
| \\d | 匹配单个数字 | String re2 = "a\\&c"; // 对应的正则是a\&c System.out.println("a&c".matches(re2)); |
| . | 匹配任意一个字符 | a.c 可以匹配abc 、 a&c 等 |
| \\w | 匹配数字字母下划线 | ac\w 可以匹配 ac1 、acb、ac_等 |
| \\s | 匹配一个空格或tab (\t) | a\sc 可以匹配 a c 和 a(tab)c |
| \\D \\W | 匹配非数字和非字符 | |
| [num1-num2] | 匹配这之间的任意一个字符 | |
| \\S | 匹配非空格 | |
| \d* | 匹配任意多个数字 | |
| \d+ | 匹配至少一个数字 | |
| \d? | 匹配0个或1个数字 | |
| \d | 精确匹配n个数字 | |
| \d | 匹配m~n个字符 |
3、复杂匹配规则
一些例子:
1、匹配开头和结尾:
^表示开头,$表示结尾;比如:
^A\d{3}$ 可以匹配 A123
2、匹配指定范围:
使用[]限定范围。匹配里面的字符或数字。比如:
[0-8] 可以匹配 0-8 (闭区间)任意一个字符
[0-9a-fA-F] 可以匹配十六进制数字
3、或匹配规则:
ad|cd 用来匹配 ab 或者 cd
String re = "java|php";
4、使用括号:
匹配多个或时 可以将公共部分抽取出来,比如:
String re = "learn\\s([jJ]ava|[pP]hp|[pP]ython)" 匹配:learn java
4、分组匹配
-
使用()来分组。主要目的是获取字符串时便捷的获取个部分内容。
比如:(\\d{3,4})\\-(\\d{7,8}) 使用Pattern 对象的 matcher方法获取一个 matcher 对象 m。 使用 m.group(index)就能获取 各个组的内容。 当 index 为零时,获取整个字符串。 -
Pattern p = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})"); Matcher m = p.matcher("010-12345678"); if (m.matches()) { String g1 = m.group(1); String g2 = m.group(2); System.out.println(g1); System.out.println(g2); } else { System.out.println("匹配失败!"); } -
使用 String 的matches 方法和 直接创建 Pattern 对象和 matcher 对象的区别
String.matches()方法内部调用的就是Pattern和Matcher类的方法。 但是反复使用String.matches()对同一个正则表达式进行多次匹配效率较低,因为每次都会创建出一样的Pattern对象。完全可以先创建出一个Pattern对象,然后反复使用,就可以实现编译一次,多次匹配实例:
Pattern pattern = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})"); pattern.matcher("010-12345678").matches(); // true pattern.matcher("021-123456").matches(); // false pattern.matcher("022#1234567").matches(); // false // 获得Matcher对象: Matcher matcher = pattern.matcher("010-12345678"); if (matcher.matches()) { String whole = matcher.group(0); // "010-12345678", 0表示匹配的整个字符串 String area = matcher.group(1); // "010", 1表示匹配的第1个子串 String tel = matcher.group(2); // "12345678", 2表示匹配的第2个子串 System.out.println(area); System.out.println(tel); }习题:获取时分秒信息:
String str = "23:12:59"; Pattern p = Pattern.compile("([0-1]\\d|2[0-3]):([0-5]\\d):([0-5]\\d)"); Matcher m = p.matcher(str); //判断是否匹配成功 if(m.matches()){ String hours = m.group(1); ...... }eles{ ...... }
5、非贪婪匹配
-
正则表达式默认使用贪婪匹配。即:对任意一个规则,总是尽可能多的向后匹配。
-
实例描述:
给定一个字符串,统计后面 0 的个数。若使用(\\d+)(0*) 分组匹配,由于贪婪匹配的存在,\\d+ 会把后面的0 也匹配到前面去。导致 0* 分组个数为0 -
解决方法:使用非贪婪匹配,在匹配规则后面加上 ?即可。\\d+?
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个数字,后面第二个?表示非贪婪匹配,因此,给定字符串"9999",匹配到的两个子串分别是""和"9999",因为对于\d?来说,可以匹配1个9,也可以匹配0个9,但是因为后面的?表示非贪婪匹配,它就会尽可能少的匹配,结果是匹配了0个9。
-
6、搜索和替换
-
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" }
-
搜索字符串:
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); } -
替换字符串
String.replaceAll()方法第一的参数是正则表达式,第二个参数是待替换的字符串。 String s = "The quick\t\t brown fox jumps over the lazy dog."; String r = s.replaceAll("\\s+", " "); 结果:"The quick brown fox jumps over the lazy dog." -
反向引用:使用replaceAll()方法的第二个参数指定对匹配到的字符串的操作
如果我们要把搜索到的指定字符串按规则替换,比如前后各加一个<b>xxxx</b>,这个时候,使用replaceAll()的时候,我们传入的第二个参数可以使用$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> "); result: the quick brown fox jumps <b>over</b> the <b>lazy</b> dog. -
################ 未理解 ####################
-
使用appendReplacement 和 appendTail 进行模板替换
-
![]()
Matcher m = pattern.matcher(template); StringBuilder sb = new StringBuilder(); while (m.find()) { m.appendReplacement(sb, data.get(m.group(1)).toString()); } m.appendTail(sb); return sb.toString(); -
用法实例:
public class TheReplacements { public static void main(String[] args) throws Exception { // 生成 Pattern 对象并且编译一个简单的正则表达式"cat" Pattern p = Pattern.compile("cat"); // 用 Pattern 类的 matcher() 方法生成一个 Matcher 对象 Matcher m = p.matcher("fatcatfatcatfat"); StringBuffer sb = new StringBuffer(); while(m.find()){ //此时sb为fatdogfatdog,cat被替换为dog,并且将最后匹配到之前的子串都添加到sb对象中 m.appendReplacement(sb,"dog"); } //此时sb为fatdogfatdogfat,将最后匹配到后面的子串添加到sb对象中 m.appendTail(sb); //输出内容为fatdogfatdogfat System.out.println("sb:"+sb); } }a b a b a a b a b a b c


浙公网安备 33010602011771号