匹配规则
注意正则表达式在Java代码中也是一个字符串,所以,对于正则表达式a&c来说,对应的Java字符串是”a\&c”,因为\也是Java字符串的转义字符,两个\实际上表示的是一个\
单个字符的匹配规则如下: 多个字符的匹配规则如下:
复杂匹配规则
分组匹配 String.matches() 正则表达式用(…)分组可以通过Matcher对象快速提取子串:
group(0)表示匹配的整个字符串;
group(1)表示第1个子串,group(2)表示第2个子串,以此类推。 eg:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import java.util.regex.*;public class Main { public static void main (String[] args) { 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("匹配失败!" ); } } }
Pattern 反复使用String.matches()对同一个正则表达式进行多次匹配效率较低,因为每次都会创建出一样的Pattern对象。完全可以先创建出一个Pattern对象,然后反复使用,就可以实现编译一次,多次匹配:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import java.util.regex.*;public class Main { public static void main (String[] args) { Pattern pattern = Pattern.compile("(\\d{3,4})\\-(\\d{7,8})" ); pattern.matcher("010-12345678" ).matches(); pattern.matcher("021-123456" ).matches(); pattern.matcher("022#1234567" ).matches(); Matcher matcher = pattern.matcher("010-12345678" ); if (matcher.matches()) { String whole = matcher.group(0 ); String area = matcher.group(1 ); String tel = matcher.group(2 ); System.out.println(area); System.out.println(tel); } } }
非贪婪匹配 在没有非贪婪匹配的时候
1 2 3 4 5 6 7 8 9 10 11 12 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 )); System.out.println("group2=" + matcher.group(2 )); } } }
正则表达式匹配默认使用贪婪匹配,可以使用?表示对某一规则进行非贪婪匹配;
1 2 3 4 5 6 7 8 9 10 11 12 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 )); System.out.println("group2=" + matcher.group(2 )); } } }
搜索和替换 分割字符串 eg:
1 2 3 "a b c" .split("\\s" ); "a b c" .split("\\s" ); "a, b ;; c" .split("[\\,\\;\\s]+" );
搜索字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 import java.util.regex.*;public 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()) { String sub = s.substring(m.start(), m.end()); System.out.println(sub); } } }
我们获取到Matcher对象后,不需要调用matches()方法(因为匹配整个串肯定返回false),而是反复调用find()方法,在整个串中搜索能匹配上\\wo\\w规则的子串,并打印出来。这种方式比String.indexOf()要灵活得多,因为我们搜索的规则是3个字符:中间必须是o,前后两个必须是字符[A-Za-z0-9_]。
替换字符串 使用正则表达式替换字符串可以直接调用String.replaceAll(),它的第一个参数是正则表达式,第二个参数是待替换的字符串。
1 2 3 4 5 6 7 8 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); } }
反向引用 如果我们要把搜索到的指定字符串按规则替换,比如前后各加一个<b>xxxx</b>,这个时候,使用replaceAll()的时候,我们传入的第二个参数可以使用$1、$2来反向引用匹配到的子串。
1 2 3 4 5 6 7 8 public class Main { 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); } }
上述代码的运行结果是:
1 the quick brown fox jumps <b>over</b> the <b>lazy</b> dog.