java正则表达式通过java.util.regex包下的Pattern类与Matcher类实现(建议在阅读本文时,打开java API文档,当介绍到哪个方法时,查看java API中的方法说明,效果会更佳).
Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式,它的构造方法是私有的,不可以直接创建,但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式。
示例代码
package com.yulore.regex;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class RegexPatternTest {
/**
* @param args
*/
public static void main(String[] args) {
// search();
// split();
// replace();
// matches();
groupTest02();
}
/**
* 当使用matches(),lookingAt(),find()执行匹配操作后,就可以利用以上三个方法得到更详细的信息.
start()返回匹配到的子字符串在字符串中的索引位置.
end()返回匹配到的子字符串的最后一个字符在字符串中的索引位置.
group()返回匹配到的子字符串
*/
public static void groupTest(){
Pattern p = Pattern.compile("\\d+");
Matcher m = p.matcher("aaa2223bb");
m.find();//匹配2223
//m.start();//返回3 m.end();//返回7,返回的是2223后的索引号 m.group();//返回2223
System.out.println("start="+m.start()+">>end="+m.end()+">>group="+m.group());
m = p.matcher("2223bb");
m.lookingAt(); //匹配2223
// m.start(); //返回0,由于lookingAt()只能匹配前面的字符串,所以当使用lookingAt()匹配时,start()方法总是返回0
//m.end(); //返回4 m.group(); //返回2223
System.out.println("start="+m.start()+">>end="+m.end()+">>group="+m.group());
m = p.matcher("2223bb");
m.matches(); //匹配整个字符串
//m.start(); //返回0,原因相信大家也清楚了
//m.end(); //返回6,原因相信大家也清楚了,因为matches()需要匹配所有字符串 m.group(); //返回2223bb
System.out.println("start="+m.start()+">>end="+m.end()+">>group="+m.group());
}
/**
* start(),end(),group()均有一个重载方法它们是start(int i),end(int i),group(int i)
* 专用于分组操作,Mathcer类还有一个groupCount()用于返回有多少组.
*/
private static void groupTest02(){
Pattern p=Pattern.compile("([a-z]+)(\\d+)");
Matcher m=p.matcher("aaa2223bb");
boolean flag = m.find(); //匹配aaa2223
int count = m.groupCount(); //返回2,因为有2组
System.out.println("flag="+flag+">>groupCount="+count);
int start = m.start(1); //返回0 返回第一组匹配到的子字符串在字符串中的索引号
int end = m.end(1); //返回3 返回第一组匹配到的子字符串的最后一个字符在字符串中的索引位置.
System.out.println("start 1 ="+start+">>"+"end 1 ="+end);
start = m.start(2); //返回3
end = m.end(2); //返回7
System.out.println("start 2 ="+start+">>"+"end 2 ="+end);
String group1 = m.group(1); //返回aaa,返回第一组匹配到的子字符串
String group2 = m.group(2); //返回2223,返回第二组匹配到的子字符串
System.out.println("group1="+group1+">>"+"group2 ="+group2);
}
/**
* split 按照指定的模式的匹配拆分给定输入序列
*/
private static void split() {
String regEx = "::";
String str = "xd::abc::cde";
Pattern p = Pattern.compile(regEx);
String[] arr = p.split(str);
// 执 行后,r就是{"xd","abc","cde"},其实分割时还有跟简单的方法:
// String[] arr =str.split("::");
for (int i = 0; arr != null && i < arr.length; i++) {
System.out.println(arr[i]);
}
}
/**
* matches 匹配
* matches()对整个字符串进行匹配,只有整个字符串都匹配了才返回true
*/
private static void matches(){
boolean bol = Pattern.matches("\\d+","2223");//返回true
System.out.println("bol1="+bol);
bol =Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
System.out.println("bol1="+bol);
bol =Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到
System.out.println("bol1="+bol);
}
/**
* lookingAt()对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true
*/
private static void lookingAt(){
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
boolean bool = m.lookingAt();//返回true,因为\d+匹配到了前面的22
System.out.println("bool="+bool);
Matcher m2=p.matcher("aa2223");
m2.lookingAt();//返回false,因为\d+不能匹配前面的aa
System.out.println("bool="+bool);
}
/**
* find()对字符串进行匹配,匹配到的字符串可以在任何位置.
*/
private static void find(){
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
boolean flag = m.find();//返回true
System.out.println("flag="+flag);
Matcher m2=p.matcher("aa2223");
flag = m2.find();//返回true
System.out.println("flag="+flag);
Matcher m3=p.matcher("aa2223bb");
flag = m3.find();//返回true
System.out.println("flag="+flag);
Matcher m4=p.matcher("aabb");
flag = m4.find();//返回false
System.out.println("flag="+flag);
}
}
1、查找某个字符中符合指定正则表达式的字串
/**
* @param args
*/
public static void main(String[] args) {
String regex = "[a]+";
String target = "aswwaaabsvasra";
search(regex,target);
}
/**
* 查找
* @param regex 指定的正则表达式
* @param target 目标字符串
*/
private static void search(String regex,String target) {
// 通过compile()方法创建Pattern实例
Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
// 通过match()创建Matcher实例
Matcher matcher = pattern.matcher(target);
while (matcher.find()){// 查找符合pattern的字符串
System.out.println("The result is here :" + matcher.group() + "\n"
+ "It starts from " + matcher.start() + " to "
+ matcher.end() + ".\n");
}
}
2、替换和删除
/**
* @param args
*/
public static void main(String[] args) {
String regex = "a";
String target = "aswwaaabsvasra";
String replace = "#";
// search(regex,target);
replace(regex, target, replace);
}
/**
* 替换/删除
* @param regex
* @param target
* @param replace
*/
private static void replace(String regex,String target,String replace) {
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(target);
String s = m.replaceAll(replace);
// String s = m.replaceFirst("a");
// 如果写成空串,既可达到删除的功能,比如:
// String s=m.replaceAll("");
System.out.println("s=" + s);
}
正则表达式的构造摘要
字符
x 字符 x
\\ 反斜线字符
\0n 带有八进制值 0 的字符 n (0 <= n <= 7)
\0nn 带有八进制值 0 的字符 nn (0 <= n <= 7)
\0mnn 带有八进制值 0 的字符 mnn(0 <= m <= 3、0 <= n <= 7)
\xhh 带有十六进制值 0x 的字符 hh
\uhhhh 带有十六进制值 0x 的字符 hhhh
\t 制表符 ('\u0009')
\n 新行(换行)符 ('\u000A')
\r 回车符 ('\u000D')
\f 换页符 ('\u000C')
\a 报警 (bell) 符 ('\u0007')
\e 转义符 ('\u001B')
\cx 对应于 x 的控制符
字符类
[abc] a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
[a-d[m-p]] a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集)
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
边界匹配器
^ 行的开头
$ 行的结尾
\b 单词边界
\B 非单词边界
\A 输入的开头
\G 上一个匹配的结尾
\Z 输入的结尾,仅用于最后的结束符(如果有的话)
\z 输入的结尾
Greedy 数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
Reluctant 数量词
X?? X,一次或一次也没有
X*? X,零次或多次
X+? X,一次或多次
X{n}? X,恰好 n 次
X{n,}? X,至少 n 次
X{n,m}? X,至少 n 次,但是不超过 m 次
Possessive 数量词
X?+ X,一次或一次也没有
X*+ X,零次或多次
X++ X,一次或多次
X{n}+ X,恰好 n 次
X{n,}+ X,至少 n 次
X{n,m}+ X,至少 n 次,但是不超过 m 次
Logical 运算符
XY X 后跟 Y
X|Y X 或 Y
(X) X,作为捕获组
Back 引用
\n 任何匹配的 nth 捕获组
反斜线、转义和引用
反斜线字符 ('\') 用于引用转义构造,如上表所定义的,同时还用于引用其他将被解释为非转义构造的字符。因此,表达式 \\ 与单个反斜线匹配,而 \{ 与左括号匹配。
在不表示转义构造的任何字母字符前使用反斜线都是错误的;它们是为将来扩展正则表达式语言保留的。可以在非字母字符前使用反斜线,不管该字符是否非转义构造的一部分。
根据 Java Language Specification 的要求,Java 源代码的字符串中的反斜线被解释为 Unicode 转义或其他字符转义。因此必须在字符串字面值中使用两个反斜线,表示正则表达式受到保护,不被 Java 字节码编译器解释。例如,当解释为正则表达式时,字符串字面值 "\b" 与单个退格字符匹配,而 "\\b" 与单词边界匹配。字符串字面值 "\(hello\)" 是非法的,将导致编译时错误;要与字符串 (hello) 匹配,必须使用字符串字面值 "\\(hello\\)"。