正则表达式

概述

  正则表达式(regular expression,regex)是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。

正则表达式书写规则

  正则表达式是定义一个“规则字符串”,把待匹配的字符串的每个字符与正则表达式的规则一一匹配,如果都匹配上,就说明该字符串满足正则表达式定义的规则。

  如果需要匹配特殊字符,则需要通过“\”转义。例如:“+”在正则表达式中是一个量词,若需要匹配“+”符号,则需要写为“\+”。

  正则表达式本身是一个字符串,所以在写转义字符时要写为“\\”。例如:“\+”在定义字符串时要写为“\\+”,“\\”在定义字符串时要写为“\\\\”等。

字符集合

  在匹配一个字符时,如果该字符只有一种可能,则在正则表达式中可以用这个字符直接书写。如果该字符有多种可能,则需要定义一个字符集合,若该字符是字符集合的一个元素,则匹配成功。正则表达式中使用“[ ]”括起若干字符表示一个字符集合。例如:

  [abc]:当前字符可以为a、b或c。

  [^abc]:当前字符可以为除了a、b、c之外的任意字符。【非】

  [A-Za-z]:当前字符可以为A~Z或a~z中的任意字符,即当前字符可以为一个字母。【含】

  [a-d[c-g]]:当前字符可以为a~d或c~g中的任意字符,等价于[a-g]。【并】

  [0-4[^0-9]]:当前字符可以为0~4或除了0~9之外的任意字符,等价于[^5-9]。

  [a-z&&[def]]:当前字符可以为a~z中的d、e或f,等价于[def]。【交】

  [a-z&&[^bc]]:当前字符可以为a~z中除了b、c之外的任意字符,等价于[ad-z]。【差】

  总结:

  1.“^”表示非,只能放在一个字符集合的开头。

  2.“-”用于连接两个字符,表示一个范围。

  3.字符集合可以嵌套。如果直接嵌套,相当于两个字符集合作并集;如果有“&&”符号,相当于两个字符集合作交集。

预定义字符集

  预定义字符集是提供常用的字符集合的缩写。

  .:任意字符。

  \d:数字字符,相当于[0-9]。

  \D:非数字字符,相当于[^0-9]。

  \s:空白字符,相当于[\t\n\x0B\f\r]。

  \S:非空白字符,相当于[^\t\n\x0B\f\r]。

  \w:词字符,相当于[A-Za-z0-9_]。

  \W:非词字符,相当于[^A-Za-z0-9_]。

量词

  正则表达式的量词用于指定匹配出现的次数。有以下几种:

  {n}:n次。

  {n,}:至少n次。

  {n,m}:n~m次。

  ?:0次或1次,相当于{0,1}。

  +:1次或多次,相当于{1,}。

  *:0次或多次,相当于{0,}。

边界匹配符

  正则表达式中的边界匹配符可以指明匹配在哪里进行,从而使模式匹配更为精确。

  ^:行的开头。

  $:行的结尾。

  \b:一个词的边界。

  \B:一个非词的边界。

  \A:输入的开头。

  \G:前次匹配的结尾。

  \Z:输入的结尾,用于带终结符的字符串。

  \z:输入的结尾。

使用正则表达式

  使用正则表达式匹配字符串主要用于3个方面:匹配整个字符串、字符串部分替换、字符串拆分。实现这3个方面有以下几种方式:

String类自带的方法

  java.lang.String类中提供了几个与正则表达式相关的方法:

  1.public boolean matches(String regex)

   判断当前字符串是否匹配。

  2.public String replaceFirst(String regex, String replacement)

   将字符串中匹配到的第一个部分替换。

  3.public String replaceAll(String regex, String replacement)

   将字符串中匹配到的所有部分替换。

  4.public String[] split(String regex, int limit)

   将字符串按照匹配到的部分拆分成指定的块数。limit指定为1时不拆分;指定为非正数或者数字过大时拆分成最多的块数。

  5.public String[] split(String regex)

   将字符串按照匹配到的部分拆分成最多的块数。

 1 @Test
 2 void testStringMethod() {
 3     String regex1 = "[\\+-]?\\d+";   // 匹配无符号或带符号的整数
 4     // 测试matches()方法
 5     System.out.println("测试matches()方法");
 6     System.out.println("\"1\"是否匹配:" + "1".matches(regex1));
 7     System.out.println("\"+23\"是否匹配:" + "+23".matches(regex1));
 8     System.out.println("\"-456\"是否匹配:" + "-456".matches(regex1));
 9     System.out.println("--------------------------");
10 
11     String regex2 = "\\w+";   // 匹配所有单词
12     String s = "abc def ghi jkl";
13     // 测试replaceFirst()方法
14     System.out.println("测试replaceFirst()方法");
15     System.out.println("替换前:" + s);
16     System.out.println("替换后:" + s.replaceFirst(regex2, "123"));
17     System.out.println("--------------------------");
18 
19     // 测试replaceAll()方法
20     System.out.println("测试replaceAll()方法");
21     System.out.println("替换前:" + s);
22     System.out.println("替换后:" + s.replaceAll(regex2, "123"));
23     System.out.println("--------------------------");
24 
25     String regex3 = "\\d+";   // 匹配无符号整数
26     String str = "abc0def12ghi345jkl6789mno";
27     // 测试split()方法
28     System.out.println("测试split()方法");
29     System.out.println("拆分前:" + str);
30     System.out.println("拆分后:" + Arrays.asList(str.split(regex3)));
31     System.out.println("拆分为1个部分:" + Arrays.asList(str.split(regex3, 1)));
32     System.out.println("拆分为3个部分:" + Arrays.asList(str.split(regex3, 3)));
33     System.out.println("拆分为6个部分:" + Arrays.asList(str.split(regex3, 6)));
34 }
testStringMethod

  输出结果:

  

Pattern类

  java.util.regex.Pattern类用于正则规范的编写。常用的方法有:

  1.public static Pattern compile(String regex)

   生成一个Pattern实例。

  2.public Matcher matcher(CharSequence input)

   生成一个Matcher实例。

  3.public static boolean matches(String regex, CharSequence input)

   判断输入串是否匹配。

  4.public String[] split(CharSequence input, int limit)

   将输入串拆分成指定的块数。limit指定为1时不拆分;指定为非正数或者数字过大时拆分成最多的块数。

  5.public String[] split(CharSequence input)

   将输入串拆分成最多的块数。

 1 @Test
 2 void testPattern() {
 3     String regex = "[\\+-]?\\d+";   // 匹配无符号或带符号的整数
 4     // 测试matches()方法
 5     System.out.println("测试matches()方法");
 6     System.out.println("\"1\"是否匹配:" + Pattern.matches(regex, "1"));
 7     System.out.println("\"+23\"是否匹配:" + Pattern.matches(regex, "+23"));
 8     System.out.println("\"-456\"是否匹配:" + Pattern.matches(regex, "-456"));
 9     System.out.println("--------------------------");
10 
11     Pattern p = Pattern.compile("\\d+");   // 匹配无符号整数
12     String str = "abc0def12ghi345jkl6789mno";
13     // 测试split()方法
14     System.out.println("测试split()方法");
15     System.out.println("拆分前:" + str);
16     System.out.println("拆分后:" + Arrays.asList(p.split(str)));
17     System.out.println("拆分为1个部分:" + Arrays.asList(p.split(str, 1)));
18     System.out.println("拆分为3个部分:" + Arrays.asList(p.split(str, 3)));
19     System.out.println("拆分为6个部分:" + Arrays.asList(p.split(str, 6)));
20 }
testPattern

  输出结果:

  

Matcher类

  java.util.regex.Matcher类用于验证字符串是否符合编译好的正则规范。Matcher实例通过Pattern的matcher()方法得到。常用的方法有:

  1.public boolean matches()

   判断字符串是否匹配。

  2.public String replaceFirst(String replacement)

   将字符串中匹配到的第一个部分替换。

  3.public String replaceAll(String replacement)

   将字符串中匹配到的所有部分替换。

  4.public Matcher reset()

   重置匹配器。

  5.public Matcher reset(CharSequence input)

   重置匹配器并替换Matcher实例中的字符串。

  6.public Matcher usePattern(Pattern newPattern)

   替换模式。

  7.public boolean find()

   从上一次查找匹配的子串的结束索引开始,查找下一个匹配的子串。若为第一次查找匹配的子串,则从0开始。

  8.public boolean find(int start)

   重置匹配器并从索引处开始查找下一个匹配的子串。

  9.public int start()

   匹配的子串的开始索引。

  10.public int end()

   匹配的子串的结束索引。

  11.public String group()

   匹配的子串。

 1 @Test
 2 void testMatcher() {
 3     Matcher matcher = Pattern.compile("").matcher("");
 4     // 测试matches()方法
 5     Matcher m1 = matcher.usePattern(Pattern.compile("[\\+-]?\\d+"));
 6     System.out.println("测试matches()方法");
 7     System.out.println("\"1\"是否匹配:" + m1.reset("1").matches());
 8     System.out.println("\"+23\"是否匹配:" + m1.reset("+23").matches());
 9     System.out.println("\"-456\"是否匹配:" + m1.reset("-456").matches());
10     System.out.println("--------------------------");
11 
12     String s = "abc def ghi jkl";
13     Matcher m2 = matcher.usePattern(Pattern.compile("\\w+")).reset(s);
14     // 测试replaceFirst()方法和replaceAll()方法
15     System.out.println("测试replaceFirst()方法");
16     System.out.println("替换前:" + s);
17     System.out.println("替换后:" + m2.replaceFirst("123"));
18     System.out.println("--------------------------");
19     System.out.println("测试replaceAll()方法");
20     System.out.println("替换前:" + s);
21     System.out.println("替换后:" + m2.replaceAll("123"));
22     System.out.println("--------------------------");
23 
24     // 测试其他方法
25     m2.reset();
26     int i = 0;
27     while (m2.find()) {
28         System.out.println("-----" + (++i) + "-----");
29         System.out.println(m2.group());
30         System.out.println("开始索引:" + m2.start());
31         System.out.println("结束索引:" + m2.end());
32     }
33 }
testMatcher

  输出结果:

  

  

 

常用的正则表达式

QQ号码

  校验规则:5~15位数字,不能以0开头。

  正则表达式:[1-9][0-9]{4,14}

邮箱

  校验规则:名称部分和域名部分都由若干个字母、数字、下划线和中划线组成;“@”位于名称和域名之间。

  正则表达式:(\\w|-)+@((\\w|-)+\\.)+(com|cn)

手机号码

  校验规则:11位数字,前3位为手机号码段。

  手机号码段:130、131、132、133、134、135、136、137、138、139、145、147、149、150、151、152、153、155、156、157、158、159、170、171、172、173、175、176、177、178、180、181、182、183、184、185、186、187、188、189、198、199

  正则表达式:(13[0-9]|14[579]|15[0-35-9]|17[0-35-8]|18[0-9]|19[89])[0-9]{8}

身份证号码

  校验规则:18位,分为6位地址码、8位出生日期码、3位顺序码和1位校验码。

  正则表达式:[0-9]{6}(18|19|20)[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])[0-9]{3}([0-9]|[xX])

posted on 2019-06-17 19:21  寇德·坡特  阅读(173)  评论(0编辑  收藏  举报

导航