Java中的Pattern、Matcher、常用的正则表达式

Java中的Pattern、Matcher、常用的正则表达式

Java中的字符串已经有了直接调用简单匹配方法,matches方法(内部也是使用了Pattern.matches()方法)

1
2
3
4
5
6
String s = "Java12Java34";
// 精确匹配,返回regex和s串是否完全匹配
boolean isMatch = s.matches("Java"); // 这里返回false
// 在一定的范围内进行匹配
// 参数的含义: 是否忽略大小写,s串的起始位置(offset),regex字符串,regex字符串的起始位置,取regex串的长度
boolean isMatch2 = s.regionMatches(true, 6, "Java", 0, "Java".length()); // 返回true

但是很多时候String自带的这些方法不足于我们使用,此时Java中提供了Pattern和Matcher两个与正则表达式相关的类供我们使用

Pattern类

1
2
String regex = "Java";
Pattern pattern = Pattern.compile(regex);

Pattern.matches()静态方法

1
2
3
String regex = "Java";
String s2 = "Java123Java456Java789";
Pattern.matches("Java", s2); // 注意这里也是全串精确匹配

其实这个方法和String中的matches()方法一致,其实String.matches()方法内部就是调用了此方法

split

顾名思义就是分割字符串的方法,其中regex就是分割字符串的”刀”,注意当regex和字符串开始或者结尾部分匹配的时候会得到空字符串

1
2
3
4
5
6
7
8
9
10
11
12
String regex = "Java";
String s2 = "Java123Java456Java789";
Pattern pattern = Pattern.compile("Java");

// split(input),分割字符串得到String数组
String[] split = pattern.split(s2);
System.out.println(split.length); // 输出3,[空串,123,456,789]

String[] split1 = pattern.split(regex, 2);
System.out.println("split1的长度为 : " + split1.length); // 输出2,[空串,123Java456Java789],想想limit设置成3会怎样?

// 注意:limit设置成0或者负数,效果默认一样,也就是和pattern.split(s2)一样

关于Pattern只介绍这两个方法,其他的可以自行创建demo试试

Matcher类

1
2
3
4
String regex = "Java";
String s = "Java123Java456Java789";
Pattern pattern = Pattern.compile(regex);
Matcher matcher1 = pattern.matcher(s);
  • find():尝试查找与该模式匹配的输入序列的的下一个子序列。重要,下面重点说
  • find(int start):重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。
  • group():匹配成功返回的组,重要,下面重点说
  • start():返回先前匹配的起始位置的索引。
  • end():返回最后匹配字符的索引加一。
  • matches():尝试将整个区域与模式匹配。匹配成功返回true
  • lookingAt():尝试将从区域开头开始的输入序列与该模式匹配。
  • replaceFirst():替换掉匹配的第一个子序列
  • replaceAll():替换掉匹配的全部子序列
  • appendReplacement:重要,下面重点说
  • appendTail(StringBuffer buf):重要,下面重点说
  • reset():重置匹配器,从起始位置重新开始
  • reset(CharSequence input):重置匹配器,放入新的待匹配的串

部分方法解析

  1. find()方法

    注意:该方法尝试查找与该模式匹配的输入序列的下一个子序列.此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了,并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配的第一个字符开始

1
2
3
4
5
6
7
8
9
10
11
12
13
String regex = "Java.";
String s = "Java1Java2";
Pattern pattern = Pattern.compile(regex);
Matcher matcher1 = pattern.matcher(s);
matcher1.find(); // 这里返回true

// 其实此时我们可以使用下面的方式来循环获取匹配得到的子串
while(matcher.find){ // 循环查找,本次查找结束了,下次如果想获得查找结果应该重新执行find()方法
System.out.println(matcher.group()); // 关于group方法将在下面介绍
}
// 上面的方法输出:
Java1
Java2
  1. group()方法

    这里介绍下组的概念:组是用括号划分的正则表达式,可以根据组的编号来引用这个组。组号为0表示整个表达式,组号为1表示被第一对括号括起的组,依次类推,例如A(B(C))D,组0是ABCD,组1是BC,组2是C。

    Matcher类提供了start(),end(),group()分别用于返回字符串的起始索引,结束索引,以及匹配到到的字符串。

    1
    2
    3
    4
    5
    6
    7
    8
    String regex = "(Java).*(Java)";
    String s = "Java123Java456";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher2 = pattern.matcher(s);
    matcher2.find(); // 注意,这里需要先执行find方法
    System.out.println(matcher2.group()); // 如果find()方法执行返回true,则group()或者group(0)代表整个字符串s:Java123Java456
    System.out.println(matcher2.group(1)); // 输出 Java123
    System.out.println(matcher2.group(2)); // 输出Java456
  2. appendReplacement(StringBuffer sb,String replacement)方法

    先从字符串中执行查找,查找到了,替换成replacement,并从开始匹配的位置处将字符串写入StringBuffer中,示例入下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    String s = "2018-4-10 15-45-30";
    String regex = "-";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(s);
    StringBuffer sb = new StringBuffer();
    matcher.find();
    matcher.appendReplacement(sb, ":");
    System.out.println(sb.toString());
    matcher.find();
    matcher.appendReplacement(sb, ":");
    System.out.println(sb.toString());
    matcher.find();
    matcher.appendReplacement(sb, ":");
    System.out.println(sb.toString());

    输出入下:
    2018:
    2018:4:
    2018:4:10 15:

    可以看到,它比String的replaceAll()或者replace()方法更加灵活

    正则表达式语法

    请参考 Java 正则表达式