原文链接 Java 正则表达式 以及Pattern ,Matcher ,PatternSyntaxException类详解
概念
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑。
符号说明
-
英文句点
.
匹配除"\r\n"之外的任何单个字符。若要匹配包括"\r\n"在内的任意字符,请使用诸如"[\s\S]"之类的模式。 -
中括号
[]
字符集。匹配包含的任一字符。例如,"[abc]"匹配"plain"中的"a"。 -
符号
^
匹配输入字符串开始的位置。如果设置了 RegExp 对象的 Multiline 属性,^ 还会与"\n"或"\r"之后的位置匹配。与[]组合成反向字符集。匹配未包含的任何字符。例如,"[^abc]"配"plain"中"p","l","i","n"。 -
表示匹配次数的符号
*
零次或多次匹配前面的字符或子表达式。<br>+
一次或多次匹配前面的字符或子表达式。<br>?
零次或一次匹配前面的字符或子表达式。<br>{n}
n 是非负整数。正好匹配 n 次。 <br>{n,}
n 是非负整数。至少匹配 n 次。 <br>{n,m}
m 和 n 是非负整数,其中 n <= m。匹配至少 n 次,至多 m 次。 -
符号
|
表示或,x|y匹配 x 或 y。 -
符号
\\
将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如, n匹配字符 n。\n 匹配换行符。序列 \\ 匹配 \ ,\( 匹配 (。 -
符号
-
与[]配合使用,表示字符范围。匹配指定范围内的任何字符。 -
符号
()
匹配 pattern 并捕获该匹配的子表达式。即正则表达式支持如算数表达式中()的运算
特殊符号说明
- \d表示[0—9]
- \D表示[^0—9]
- \w表示[0—9A—Z_a—z]
- \W表示[^0—9A—Z_a—z]
- \s表示[\t\n\r\f]
- \S表示[^\t\n\r\f]
java.util.regex 包下主要三个类
Pattern类
//常用函数 | |
//Compiles the given regular expression into a pattern.编译为pattern对象 | |
public static Pattern compile(String regex) { | |
return new Pattern(regex, 0); | |
} | |
// 创建Matcher对象,用于匹配字符串 | |
public Matcher matcher(CharSequence input) { | |
if (!compiled) { | |
synchronized(this) { | |
if (!compiled) | |
compile(); | |
} | |
} | |
Matcher m = new Matcher(this, input); | |
return m; | |
} | |
//匹配字符串 | |
public static boolean matches(String regex, CharSequence input) { | |
Pattern p = Pattern.compile(regex); | |
Matcher m = p.matcher(input); | |
return m.matches(); | |
} | |
// 字符串拆分,String中的split函数底层就是 | |
// return Pattern.compile(regex).split(this, limit); | |
public String[] split(CharSequence input, int limit) ; | |
.....省略 |
小结
Pattern类对于正则表达式,先进行编译,并且Pattern 类没有公共构造方法。要创建一个 Pattern 对象,你必须首先调用其公共静态编译方法,它返回一个 Pattern 对象。该方法接受一个正则表达式作为它的第一个参数。最后再通过matcher 进行字符串的匹配。
Matcher 类:
Matcher 对象是对输入字符串进行解释和匹配操作的引擎。
//创建此匹配器的Pattern 对象。 | |
Pattern parentPattern; | |
//设置Pattern对象,以及需要匹配的字符串 | |
Matcher(Pattern parent, CharSequence text) { | |
this.parentPattern = parent; | |
this.text = text; | |
// Allocate state storage | |
int parentGroupCount = Math.max(parent.capturingGroupCount, 10); | |
groups = new int[parentGroupCount * 2]; | |
locals = new int[parent.localCount]; | |
// Put fields into initial states | |
reset(); | |
} | |
//重设Pattern对象 | |
public Matcher usePattern(Pattern newPattern); | |
//重设Matcher 状态,设置新的字符串 | |
public Matcher reset(); | |
public Matcher reset(CharSequence input) { | |
text = input; | |
return reset(); | |
} | |
//Matcher.matches()、Matcher.lookingAt()、Matcher.find() | |
//Matcher.matches()是堆整个字符串进行匹配 | |
public boolean matches() { | |
return match(from, ENDANCHOR); | |
} | |
//Matcher.lookingAt()从开头开始匹配。即从第一个字母就开始匹配,但不需要匹配整个字符串 | |
public boolean lookingAt() { | |
return match(from, NOANCHOR); | |
} | |
//Matcher.find()尝试寻找与模式匹配的输入序列的下一个子序列,就是能匹配到子序列就行了 | |
public boolean find() { | |
int nextSearchIndex = last; | |
if (nextSearchIndex == first) | |
nextSearchIndex++; | |
// If next search starts before region, start it at region | |
if (nextSearchIndex < from) | |
nextSearchIndex = from; | |
// If next search starts beyond region then it fails | |
if (nextSearchIndex > to) { | |
for (int i = 0; i < groups.length; i++) | |
groups[i] = -1; | |
return false; | |
} | |
return search(nextSearchIndex); | |
} | |
// Mathcer.start()、Matcher.end()、Matcher.group() | |
//当执行了当使用matches(),lookingAt(),find()执行匹配操作后,就可以利用以上三个方法得到更详细的信息: | |
//start()返回匹配到的子字符串的第一个字符在原字符串中的索引位置; | |
//end()返回匹配到的子字符串的最后一个字符在原字符串中的索引位置; | |
//group()返回匹配到的子字符串。 | |
//只有当匹配操作成功,才可以使用start(),end(),group()三个方法 | |
//对group分析 | |
//调用group()其实是group(0) | |
public String group() { | |
return group(0); | |
} | |
// | |
public String group(int group); | |
String content = "I am noob " + | |
"from runoob.com."; | |
String pattern = "(oo).*(com)"; | |
Pattern com= Pattern.compile(pattern); | |
Matcher matcher =com.matcher(content); | |
while(matcher.find()) | |
{ | |
System.out.println("matcher.group(0) "+matcher.group(0));//得到第0组——整个匹配 | |
System.out.println("matcher.group(0) "+matcher.group(1));//得到第1组——整个匹配 | |
System.out.println("matcher.group(0) "+matcher.group(2));//得到第2组——整个匹配 | |
/** | |
*matcher.group(0) oob from runoob.com | |
*matcher.group(0) oo | |
*matcher.group(0) com | |
*即group(0)是返回整个正则表达式匹配的结过 | |
*index参数表示每个()内的子正则表达式的结果 | |
*/ | |
//可以通过while(m.find())来获取所有匹配的字符串 | |
while (m.find()) { | |
System.out.println(m.group()); | |
System.out.print("start:" + m.start()); | |
System.out.println(" end:" + m.end()); | |
} | |
//Mathcer.replaceAll(String replacement) 和 Mathcer.replaceFirst(String replacement),String replace的底层也是这个函数 | |
//将最后一次匹配工作后剩余的字符串添加到一个StringBuffer对象里。 | |
public StringBuffer appendTail(StringBuffer sb) { | |
sb.append(getSubSequence(lastAppendPosition, getTextLength()).toString()); | |
return sb; | |
} | |
// 将区域设置为从 start 参数指定的索引处开始,并在 end 参数指定的索引处结束。 | |
public Matcher region(int start, int end); | |
小结
匹配字符串的具体操作都在matcher上
PatternSyntaxException类
表达式错误异常
总结
Pattern与Matcher共同进行字符串匹配,Matcher类提供了对正则表达式的分组支持,以及对正则表达式的多次匹配支持. 单独用Pattern只能使用Pattern.matches(String regex,CharSequence input)一种最基础最简单的匹配。
操作代码:
Pattern pattern = Pattern.compile("regex"); | |
Matcher m = pattern.matcher("str"); | |
//再根据需求,调用Matcher的函数即可 |