Java-正则表达式
正则表达式是一个强大的字符串处理工具,可以对字符串进行查找、提取、分割、替换等操作。
String类提供的几个特殊方法
判断字符串是否匹配指定的正则表达式
boolean matches(String regex)
所有匹配regex的子串替换replacement
String replaceAll(String regex, String replacement)
将第一个匹配regex的子串替换成replacement
String replaceFirst(String regex, String replacement)
以regex作为分隔符,把该字符串分割为多个子串
String[] split(String regex)
Java提供了Pattern和Matcher两个类专门用于提供正则表达式
创建正则表达式
正则表达式中特殊字符
特殊字符 | 说明 |
---|
$ | 匹配一行的结尾 |
^ | 匹配一行的开头 |
( ) | 标记子表达式的开始和结束位置 |
[ ] | 用于确定中括号表达式的开始和结束位置 |
{ } | 用于指定前面子表达式的出现频度 |
* | 指定前面子表达式可以出现零次或者多次 |
+ | 指定前面子表达式可以出现一次或多次 |
? | 指定前面子表达式可以出现零次或一次 |
. | 匹配出了换行符\n之外的任何单字符 |
\ | 用于转义下一个字符,或指定八进制、十六进制字符 |
| | 指定两项之间任选一项 |
如果要匹配这些特殊字符,首先将这些字符进行转义,也就是在前面加一个反斜杠(\)
即匹配 ^ 本身需要使用 ^
正则表达式的“通配符”,预定义字符
预定义字符 | 说明 |
---|
. | 可以匹配任何字符 |
\d | 匹配0~9的所有数字 |
\D | 匹配非数字 |
\s | 匹配所有的空白字符,包括空格、制表符、回车符、换页符、换行符等 |
\S | 匹配所有非空白字符 |
\w | 匹配所有单词字符,包括0~9所有数字、26个英文字母和下画线(_) |
\W | 匹配所有非单词字符 |
d 表示 digit ,代表数字
s 表示 space , 代表空白
w 是 word, 代表字母
d、s、w 的大写形式恰好匹配与之相反的字符
c\\wt
\\d\\d\\d-\\d\\d\\d-\\d\\d\\d\\d
方括号表达式
方括号表达式 | 说明 |
---|
表示枚举 | 例如[abc],表示 a、b、c 其中任意一个字符; |
表示范围: - | 例如[a-f],表示 a~f 范围内任意字符,范围可枚举结合,如[a-cx-z]匹配ac,xz任意字符 |
表示求否: ^ | 例如[ ^abc ],表示非a、b、c的任意字符;[ ^a-f] 表示不是a~f范围内的任意字符 |
表示“与”运算: && | 例如[a-z&&[def]],求a~z和[def]的交集; [a-z&&[ ^m-p]]求a~z的所有字符除了m-p范围外 |
表示“并”运算 | 并运算与前面的枚举类似,例如[a-d[m-p]],表示[a-dm-p] |
若需要匹配所有的中文字符,就可以利用[\ \u0041-\ \u0056]形式
因为所有中文字符的Unicode值是连续的,只要找出所有中文字符中最小、最大的Unicode值,就可以利用上方形式来匹配所有的中文字符
边界匹配符
边界匹配符 | 说明 |
---|
^ | 行的开头 |
$ | 行的结尾 |
\b | 单词的边界 |
\B | 非单词的边界 |
\A | 输入的开头 |
\G | 前一个匹配的结尾 |
\Z | 输入的结尾,仅用于最后的结束符 |
\z | 输入的结尾 |
三种模式的数量表示符
Greedy(贪婪模式):数量表示符默认采用贪婪模式,除非另有表示。贪婪模式的表达式会一直匹配下去,直到无法匹配为止。
Relcutant(贪婪模式):用问好后缀(?)表示,它只会匹配最少的字符。
Possessive(占有模式):用加号后缀(+)表示,目前只有Java支持占有模式,通常比较少用
贪婪模式 | 勉强模式 | 占用模式 | 说明 |
---|
X? | X?? | X?+ | X表达式出现零次或者一次 |
X* | X*? | X*+ | X表达式出现零次或者多次 |
X+ | X+? | X++ | X表达式出现一次或者多次 |
X{n} | X{n}? | X{n}+ | X表达式出现n次 |
X{n,} | X{n,}? | X{n,}+ | X表达式最少出现n次 |
X{n,m} | X{n,m}? | X{n,m}+ | X表达式最少出现n次,最多出现m次 |
使用正则表达式
一旦在程序中定义了正则表达式,就可以是用Pattern和Matcher来使用正则表达式
Pattern对象是正则表达式编译后在内存中的表达形式,因此,正则表达式字符串必须先被编译成Pattern对象,然后再利用Pattern对象创建对应的Matcher对象。
执行匹配所涉及的状态保留在Matcher对象中,多个Matcher对象可共享同一个Pattern对象。
因此,典型的调用顺序如下:
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
如果正则表达式仅需要一次使用
boolean b = Pattern.matches("a*b","aaaaab");
Pattern是不可变类,可供多个并发线程安全使用
Matcher类提供了几个常用方法
find(); 返回目标字符串中是否包含于Pattern匹配的子串
group(); 返回上一次与Pattern匹配的子串
start(); 返回上一次与Pattern匹配的子串在目标字符串中的开始位置
end(); 返回上一次与Pattern匹配的子串在目标字符串中的结束位置加一
lookingAt(); 返回目标字符串前面部分与Pattern是否匹配
matches(); 返回整个目标字符串与Pattern是否匹配
reset(); 将现有的Matcher对象应用于一个新的字符序列
程序示范
FindGroup.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FindGroup {
public static void main(String[] args) {
String str = "我想求购一本《疯狂Java讲义》,尽快联系我13500006666" + "交朋友,电话号码是13611125565" + "出售二手电脑,联系方式15899903312";
Matcher matcher = Pattern.compile("((13\\d)|(15\\d))\\d{8}").matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
}
}
}
StartEnd.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class StartEnd {
public static void main(String[] args) {
String regStr = "Java is very easy!";
System.out.println("目标字符串是:" + regStr);
Matcher m = Pattern.compile("\\w+").matcher(regStr);
while (m.find()) {
System.out.println(m.group() + "子串的起始位置:" + m.start() + ",其结束位置:" + m.end());
}
}
}
MatchesTest.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MatchesTest {
public static void main(String[] args) {
String[] mails = { "kongyeeku@163.com", "kongyeeku@gmail.com", "ligang@crazyit.org", "wawa@abc.xx" };
String mailRegEx = "\\w{3,20}@\\w+\\.(com|org|cn|net|gov)";
Pattern mailPattern = Pattern.compile(mailRegEx);
Matcher matcher = null;
for (String mail : mails) {
if (matcher == null) {
matcher = mailPattern.matcher(mail);
} else {
matcher.reset(mail);
}
String result = mail + (matcher.matches() ? "是" : "不是") + "一个有效的邮件地址!";
System.out.println(result);
}
}
}
ReplaceTest.java
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ReplaceTest {
public static void main(String[] args) {
String[] msgs = { "Java has regular expressions in 1.4", "regular expressions now expressing in Java",
"Java represses oracular expressions" };
Pattern p = Pattern.compile(" re\\w*");
Matcher matcher = null;
for (int i = 0; i < msgs.length; i++) {
if (matcher == null) {
matcher = p.matcher(msgs[i]);
} else {
matcher.reset(msgs[i]);
}
System.out.println(matcher.replaceAll("哈哈:)"));
}
}
}
StringReg.java
package carzy.java.codes07;
import java.util.Arrays;
public class StringReg {
public static void main(String[] args) {
String[] msgs = { "Java has regular expressions in 1.4", "regular expressions now expressing in Java",
"Java represses oracular expressions" };
for (String msg : msgs) {
System.out.println(msg.replaceFirst("re\\w*", "哈哈:)"));
System.out.println(Arrays.toString(msg.split(" ")));
}
}
}