基础符号

首尾匹配^:匹配输入字符串开始的位置

$:匹配输入字符串结尾的位置

例:"^hello$"含义为该字符串开头必须为h,结尾必须为oprivate static void demo1() {

String content = "hello";
String pattern = "^hello$";
boolean isMatch = Pattern.matches(pattern, content);
System.out.println(content + "与" + pattern + "是否匹配?" + isMatch);
}

匹配数量:*:0个或多个

+:一个或多个

?:0个或1个

{n}:n个

{n,}:n到无穷多个

{n,m}:n到m个

例:

匹配0-6个hprivate static void demo2() {
String[] s = {"h", "hh", "hhh", "hhhh", "hhhhh", "hhhhhh"};
String[] p = {"h+", "h*", "h?", "h{3}", "h{3,}", "h{3,5}"};
for (String content : s) {
for (String pattern : p) {
boolean isMatch = Pattern.matches(pattern, content);
System.out.println(content + "\t与\t" + pattern + "\t是否匹配?\t" + isMatch);
}
}
}h+h*h?h{3}h{3,}h{3,5}空字符串011000
h111000
hh110000
hhh110111
hhhh110011
hhhhh110011
hhhhhh110010

捕获方式:(pattern):()表示捕获分组,()会把每个分组里的匹配的值保存起来,从左向右,以分组的左括号为标志,第一个出现的分组的组号为1,第二个为2,以此类推

(?:pattern):表示非捕获分组,和捕获分组唯一的区别在于,非捕获分组匹配的值不会保存起来

(?=pattern):正向肯定预查,匹配pattern前面的位置。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。

(?!pattern):正向否定预查(negative assert),在任何不匹配pattern的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。

(?<=pattern):反向(look behind)肯定预查,与正向肯定预查类似,只是方向相反。

(?

方括号:

[xyz]:匹配x或y或z

[^xyz]:匹配除了x、y、z的其他字符

[a-z]:匹配小写字母

转义:\b\B:\b匹配一个字边界,即字与空格间的位置。例如,"lo\b"匹配"hello"中的"ol",但不匹配"look"中的"lo"。\B反之。

\cx:\cx 匹配control + 控制字符\cI 匹配 control + I,等价于 \t,

\cJ匹配 control + J,等价于 \n,

\cM匹配 control + M,等价于 \r

\ca \cb \cc ... 又分别匹配 control+a, control+b,control+c....,看运行的程序而定

\d\D:\d匹配数字。\D匹配非数字

\f:匹配分页符。等效于 \x0c 和 \cL。

\n:匹配换行符。等效于 \x0a 和 \cJ。

\r:匹配回车符。等效于 \x0d 和 \cM。

\s\S:\s匹配任何空白字符,包括空格、制表符、换页符等。与 [ \f\n\r\t\v] 等效。

\t:制表符匹配。与 \x09 和 \cI 等效。cv

\v:匹配垂直制表符。与 \x0b 和 \cK 等效。

\w\W:\w匹配任何字类字符,包括下划线。与"[A-Za-z0-9_]"等效。\W反之

捕获组

从正则表达式左侧开始,每出现一个左括号"("记做一个分组,分组编号从1开始。0代表整个表达式。而命名则在括号中加入?给其命名

比如对于时间字符串:2019-01-20,表达式如下:(?\\d{4})-(?(?\\d{2})-(?\\d{2}))

有4个左括号,所以有4个分组:编号名称捕获组匹配00(\d{4})-((\d{2})-(\d{2}))    整体2019-01-20

1year(\d{4})2019

2md((\d{2})-(\d{2}))01-20

3month(\d{2})01

4date(\d{2})20

示例代码:

private static void demo5() {
Pattern p = Pattern.compile("(\\d{4})-((\\d{2})-(\\d{2}))");
Matcher m = p.matcher("2019-01-20");
m.find();
System.out.println("m.group(0) value: "+m.group(0));
System.out.println("m.group(1) value: "+m.group(1));
System.out.println("m.group(2) value: "+m.group(2));
System.out.println("m.group(3) value: "+m.group("month"));
System.out.println("m.group(4) value: "+m.group("date"));
}
//

输出:

//m.group(0) value: 2019-01-20
//m.group(1) value: 2019
//m.group(2) value: 01-20
//m.group(3) value: 01
//m.group(4) value: 20

Java常用类

Pattern 类:pattern 对象是一个正则表达式的编译表示。Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。

Matcher 类:Matcher 对象是对输入字符串进行解释和匹配操作的引擎。与Pattern 类一样,Matcher 也没有公共构造方法。你需要调用 Pattern 对象的 matcher 方法来获得一个 Matcher 对象。

PatternSyntaxException类:是一个非强制异常类,它表示一个正则表达式模式中的语法错误。

Matcher方法

索引方法序号方法说明1public int start()返回以前匹配的初始索引。

2public int start(int group)返回在以前的匹配操作期间,由给定组所捕获的子序列的初始索引

3public int end()返回最后匹配字符之后的偏移量。

4public int end(int group)返回在以前的匹配操作期间,由给定组所捕获子序列的最后字符之后的偏移量。

public class RegexMatches {
public static void main(String[] args) {
Pattern p = Pattern.compile("\\bwen\\b");
Matcher m = p.matcher("wen wen wenXXX wen"); // 获取 matcher 对象
int count = 0;
while (m.find()) {
count++;
System.out.print("第" + count+"个匹配值 ");
System.out.print("起始索引: " + m.start());
System.out.print(" 结束索引: " + m.end());
System.out.println();
}
}
private static void demo() {
Pattern p = Pattern.compile("(\\d{4})-((\\d{2})-(\\d{2}))");
Matcher m = p.matcher("2019-01-20");
m.find();
for(int i=0;i<5;i++){
System.out.println("第"+i+"个组"+"索引 "+m.start(i)+" 值:"+m.group(i));
}
}
}

main输出:第1个匹配值 起始索引: 0 结束索引: 3

第2个匹配值 起始索引: 4 结束索引: 7

第3个匹配值 起始索引: 15 结束索引: 18

demo输出:第0个组索引 0 值:2019-01-20

第1个组索引 0 值:2019

第2个组索引 5 值:01-20

第3个组索引 5 值:01

第4个组索引 8 值:20

查找方法序号方法说明1public boolean lookingAt()判断开头区域是否与正则表达式匹配。

2public boolean find()尝试查找与该表达式匹配的输入序列的下一个子序列。

3public boolean find(int start)重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列。

4public boolean matches()判断整个区域是否与正则表达式匹配。

例:

public class RegexMatches2 {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("foo");
Matcher matcher = pattern.matcher("fooooooooooooooooo");
Matcher matcher2 = pattern.matcher("ooooofoooooooooooo");
System.out.println("lookingAt(): " + matcher.lookingAt());
System.out.println("matches(): " + matcher.matches());
System.out.println("lookingAt(): " + matcher2.lookingAt());
}
}

输出:

lookingAt(): true
matches(): false
lookingAt(): false

替换方法序号方法说明1public Matcher appendReplacement(StringBuffer sb, String replacement)实现非终端添加和替换步骤。

2public StringBuffer appendTail(StringBuffer sb)实现终端添加和替换步骤。

3public String replaceAll(String replacement)替换模式与给定替换字符串相匹配的输入序列的每个子序列。

4public String replaceFirst(String replacement)替换模式与给定替换字符串匹配的输入序列的第一个子序列。

5public static String quoteReplacement(String s)返回指定字符串的字面替换字符串。这个方法返回一个字符串,就像传递给Matcher类的appendReplacement 方法一个字面字符串一样工作。

replaceAll案例:

private static void demo1() {
String dog = "I have a dog. The dog very cute.";
Pattern p = Pattern.compile("dog");
Matcher m = p.matcher(dog);
dog = m.replaceAll("cat");
System.out.println(dog);
}

输出:

I have a cat. The cat very cute.
replaceFirst

案例:

private static void demo2() {
String dog = "I have a dog. The dog very cute.";
Pattern p = Pattern.compile("dog");
Matcher m = p.matcher(dog);
dog = m.replaceFirst("cat");
System.out.println(dog);
}

输出:

I have a cat. The dog very cute.
appendReplacement 和 appendTail 方法private static void demo3() {
Pattern p = Pattern.compile("a*b");
// 获取 matcher 对象
Matcher m = p.matcher("aabfooaabfooabfoobkkk");
StringBuffer sb = new StringBuffer();
while(m.find()){
m.appendReplacement(sb,"-");
System.out.println(sb.toString());
}
m.appendTail(sb);
System.out.println(sb.toString());
}