正则表达式是一种强大而灵活的文本处理工具。使用正则表达式,我们能够以编程的方式,构造复杂的文本模式,并对输入的字符串进行搜索。 一般来说,正则表达式就是以某种方式来描述字符串。“如果一个字符串含有这些东西,那么他就是我正在找的东西”。本文主要讲解java中正则表达式的基础知识。
正则表达式元素介绍
正则表达式定义的元素有:元字符、字符类、转义字符、限定符、反义、逻辑或、分组。
- 元字符
^ 从开始位置开始匹配
\s 匹配空白字符(如空格、制表符、换行符等)
$ 匹配到结束位置
\S 匹配非空白字符
\b 匹配单词的开始或结束位置
\d 匹配数字字符(0-9)
. 匹配除换行符这外的任意字符
\D 匹配非数字字符
\w 匹配单字字符(a-z、A-Z、0-9及下划线)
\W 匹配非单字字符
字符类
匹配字符集合。字符类就是方括号中的一个字符集,即匹配括号内的任意字符。
如:[1234] 匹配1234中任一一个数字
[a-zA-Z] 匹配a到z,A到Z之间的任一字符
[a-zA-Z0-9][ a-zA-Z0-9] [a-zA-Z0-9][ a-zA-Z0-9] 匹配4位的验正码转义字符
“^”、“$”、“.”这样的字符都是特殊字符,若想将特殊字符当普通字符使用,需要使用转义字符“\”将特殊字符转义成普通字符。限定符
用于指定字符或字符集出现的次数
“ * ” 出现0到多次,最少0次。
“ + ”出现1到多次,最少1次。
“ ? ”出现0或1次
“ {m} ”出现m次,m>=0.
“ {m,} ”至少出现m次,m>=0.
“ {m,n} ”至少出现m次,最多出现n次,0<=m<=n反义
匹配字符集以外的字符,可以使用反义字符“^”。
如:[^0-9] :表示除0-9之外的字符。- 逻辑或
字符串匹配正则表达式中字符“|”的左边或右边的规则,则字符串匹配正则表达式。
如:固定电话(4位区号-7位号码或3位区号-8位号码):0\d{3}-\d{7}|0\d{2}-\d{8} 分组
可以用 “ ( ” 和 “ ) ” 将正则表达式分成一个一个组,两个括号中的看成一个整体。
这里可用于Matcher.group()中组的计算。
例如,在表达式((A)(B(C))),有四个这样的组:((A)(B(C)))
(A)
(B(C))
(C)字符串中使用正则表达式
字符串使用正则表达式主要有三个方法:
三个方法见名知义,不多做介绍。matches()
s.matches(): 匹配字符串s是否符合给定的正则表达式格式。- split()
s.split() : 拆分字符串.可以根据一个正则表达式拆分。 - replaceAll()
s.replaceAll():将字符处串s中符合正则表达式描述的内容替换为给定的字符串。
Pattern类
Pattern对象表示一个已编译的正则表达式。该类没有提供公共的构造器。要创建它的对象,需要调用该类的compile()静态方法。
- 创建对象的两种方法:
Pattern pattern = Pattern.compile(regex);
Pattern pattern = Pattern.compile(regex, flags);
第一个入参为正则表达式(regex);
第二个入参为模式标记(flags)(CASE_INSENSITIVE匹配字符时与大小写无关、UNICODE_CASE使用Unicode字母匹配等),本参数的更多值请查询文档。
- pattern的方法
compile(regex) 给指定的regex正则表达式编译,返回Pattern对象
compile(regex, flags) 给指定的regex正则表达式和模式标记编译,返回Pattern对象
matcher(input) Pattern类创建Matcher对象(较常用)
matcher(regex,input) Pattern类将指定的regex正则表达式与输入的input字符串进行匹配,返回
Matcher对象
Matcher类
Matcher类是依靠输入的字符串来解析这个模式和完成匹配操作的对象。该类也无构造器,可通过调用Pattern对象的matcher()方法创建对象。
- 创建对象
Matcher matcher = Pattern.compile(regex).matcher(input);
regex为正则表达式;input为输入的字符串。 - 常用方法
group() 代表了整个匹配的字符串
start() 返回当前匹配到的字符串在原目标字符串中的位置
end() 返回当前匹配的字符串在原目标字符串中的最后一个位置的索引位置
find() 匹配字符串,匹配到的字符串可以在任何位置
其中,group方法可返回给定字符串对应的组(也即子字符串),可使用group(0),group(1)等来获取对应的组。可使用groupCount()方法来获取该正则表达式共有多少组(group(0)不包括在内)。
具体理解可以结合代码来理解:
需要特别指出的是,在使用group(i)来获取组时,需要按照指定的正则表达式来划分组,而不是按照输入的字符串来划分。以下面代码为例。在取match的group(i)时,应该这样理解,生成match的正则表达式是regex=”(\D*)(\d+)(\D*)(.)”,按照正则表达式元素介绍中的分组介绍,这个正则表达式可划分为5个组:”(\D)(\d+)(\D*)(.)”,”(\D)”,”(\d+)”,”(\D*)”,”(.*)”。然后分别对应于输入的字符串,找出group(0)~group(4)一共5个组。
public class PatternAndMathcer {
public static void main(String[] args) {
String regex="(\\D*)(\\d+)(\\D*)(.*)";
String input="This order was 2000placed for QT3000! OK?";
Pattern pat=Pattern.compile(regex);
Matcher match=pat.matcher(input);
/**
* find() 是插在是否有匹配到的字符串,匹配到返回true,反之false
* group()返回匹配到的子字符串。以()进行划分。划分时以正则表达式为准不是以输入的字符串为准。
*/
System.out.println(match.groupCount()); //4
while(match.find()){
System.out.println(match.start()); //0
System.out.println(match.end()); //41
System.out.println(input.length()); //41
System.out.println("Found value: " +match.group(0)); //This order was 2000placed for QT3000! OK?
System.out.println("Found value: " +match.group(1)); //This order was
System.out.println("Found value: " +match.group(2)); //2000
System.out.println("Found value: " +match.group(3)); //placed for QT
System.out.println("Found value: " +match.group(4)); //3000! OK?
}
}
}