正则表达式:搜索、编辑和操作字符,模式会从左到右匹配文本。
编写规则:
常见匹配符号:
- . 匹配所有单个字符,除了换行符号
- ^regex 匹配的字符的开头必须是regex
- regex$ 匹配的字符的结尾必须是regex
- [abc] 复选集定义,匹配字母为 a或者b或者c
- [^abc] 当^ 在中括号中以第一个字符开始,则表示否定模式,此匹配除了a或b或c的所有的字符。
- [a-d1-7] 匹配a到d 的字符和1到7的数字。
- X|Z 匹配 X或者Z
元字符:一个预定义的字符
- \d 匹配一个数字,等价于 [0-9]
- \D 匹配一个非数字,等价于 [^0-9]
- \s 匹配一个空格 等价于[\t\n\x0b\r\f] 的缩写
- \S 匹配一个非空格
- \w 匹配一个单词符号,包括大小写,数字,下划线,等价于 [a-zA-Z_0-9]
- \W 匹配一个非单词字符,除包括大小写,数字,下划线之外,等同于[^\w]
限定符号:定义一个元素可以发送的频率
- * 匹配>= 0个,等价于{0,}
- + 匹配>= 1个,等价于{1,}
- ? 匹配0个或者1个,等价于{0,1}
- {X} 只匹配X个字符,\d{3}匹配3个数字, {10}表示匹配任何长度使10得字符串
- {X,Y} 匹配>=X 且 <= Y 个,\d{1,4} 表示匹配至少一个最多4个数字
- *? 如果
?
是限定符*
或+
或?
或{}
后面的第一个字符,那么表示非贪婪模式(尽可能少的匹配字符而不是默认的贪婪模式
分组和反向引用:
// 去除单词与 , 和 . 之间的空格
String Str = "Hello , World .";
String pattern = "(\\w)(\\s+)([.,])";
// $0 匹配 `(\w)(\s+)([.,])` 结果为 `o空格,` 和 `d空格.`
// $1 匹配 `(\w)` 结果为 `o` 和 `d`
// $2 匹配 `(\s+)` 结果为 `空格` 和 `空格`
// $3 匹配 `([.,])` 结果为 `,` 和 `.`
// 我们使用了 [.] 来匹配普通字符 . 而不需要使用 [\\.]。因为正则对于 []
// 中的 .,会自动处理为 [\.],即普通字符 . 进行匹配。
System.out.println(Str.replaceAll(pattern, "$1$3")); // Hello, World.
小括号()可以达到对正则表达式进行分组的效果
反斜杠 \
在 Java 中表示转义字符,这意味着 被转义的字符在 Java 拥有预定义的含义。
- 在匹配
.
或{
或[
或(
或?
或$
或^
或*
这些特殊字符时,需要在前面加上\
,比如匹配.
时,但对于正则表达式来说就是\.
。 - 在匹配
\
时,对于正则表达式来说就是\\
内置字符串正则处理方法:
System.out.println("wjx".matches("wjx"));
String[] split = "x c f".split("\\s");
for (String s:split) {
System.out.println(s);
}
System.out.println("------------");
System.out.println("x v f".replaceAll("\\s", "-"));
Java 模式匹配
java 中的正则表达式类,java.util.regex.Pattern
和 java.util.regex.Matcher
步骤如下:
通过正则表达式创建模式对象,Pattern
通过模式
Pattern ,根据指定字符串创建匹配对象 Matcher- 通过匹配对象 Matcher, 根据正则表达式操作字符。
public static void p3(){
String text = "Hello Regex";
Pattern pattern = Pattern.compile("\\w+");
Matcher matcher = pattern.matcher(text);
while (matcher.find()){
System.out.println("start index " +matcher.start());
System.out.println("end index " +matcher.end());
System.out.println(matcher.group());
}
}
类使用详解
捕获组的概念:捕获组可以通过从左到右计算其开括号来编号,编号是从1 开始的。例如,在表达式 ((A)(B(C)))中,存在四个这样的组:
1 ((A)(B(C)))
2 (A)
3 (B(C))
4 (C)
组零始终代表整个表达式。
Pattern类用于创建一个正则表达式,也可以说创建一个匹配模式。但可以通过Pattern.complie(String regex)简单工厂方法创建一个正则表达式。
Pattern p=Pattern.compile("\\w+");
p.pattern();//返回 \w+
1.Pattern.split(CharSequence input) 用于分隔字符串,并返回一个String[]
Pattern p=Pattern.compile("\\d+");
String[] str=p.split("我的QQ是:456456我的电话是:0532214我的邮箱是:aaa@aaa.com");
结果:str[0]="我的QQ是:" str[1]="我的电话是:" str[2]="我的邮箱是:aaa@aaa.com"
2 Pattern.matcher(String regex,CharSequence input)是一个静态方法,用于快速匹配字符串,该方法适合用于只匹配一次,且匹配全部字符串.
Pattern.matches("\\d+","2223");//返回true
Pattern.matches("\\d+","2223aa");//返回false,需要匹配到所有字符串才能返回true,这里aa不能匹配到
Pattern.matches("\\d+","22bb23");//返回false,需要匹配到所有字符串才能返回true,这里bb不能匹配到
3.Pattern.matcher(CharSequence input) Pattern.matcher(CharSequence input)返回一个Matcher对象.
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.pattern();//返回p 也就是返回该Matcher对象是由哪个Pattern对象的创建的
4.Matcher.matches()/ Matcher.lookingAt()/ Matcher.find()
三个方法均返回boolean类型,当匹配到时返回true,没匹配到则返回false
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.matches();//返回false,因为bb不能被\d+匹配,导致整个字符串匹配未成功.
Matcher m2=p.matcher("2223");
m2.matches();//返回true,因为\d+匹配到了整个字符串
lookingAt()对前面的字符串进行匹配,只有匹配到的字符串在最前面才返回true
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.lookingAt();//返回true,因为\d+匹配到了前面的22
Matcher m2=p.matcher("aa2223");
m2.lookingAt();//返回false,因为\d+不能匹配前面的aa
find()对字符串进行匹配,匹配到的字符串可以在任何位置.
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("22bb23");
m.find();//返回true
Matcher m2=p.matcher("aa2223");
m2.find();//返回true
Matcher m3=p.matcher("aa2223bb");
m3.find();//返回true
Matcher m4=p.matcher("aabb");
m4.find();//返回false
5.Mathcer.start()/ Matcher.end()/ Matcher.group()
start()返回匹配到的子字符串在字符串中的索引位置.
end()返回匹配到的子字符串的最后一个字符在字符串中的索引位置.
group()返回匹配到的子字符串
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("aaa2223bb");
m.find();//匹配2223
m.start();//返回3
m.end();//返回7,返回的是2223后的索引号
m.group();//返回2223
Mathcer m2=m.matcher("2223bb");
m.lookingAt(); //匹配2223
m.start(); //返回0,由于lookingAt()只能匹配前面的字符串,所以当使用lookingAt()匹配时,start()方法总是返回0
m.end(); //返回4
m.group(); //返回2223
Matcher m3=m.matcher("2223bb");
m.matches(); //匹配整个字符串
m.start(); //返回0,原因相信大家也清楚了
m.end(); //返回6,原因相信大家也清楚了,因为matches()需要匹配所有字符串
m.group(); //返回2223bb
正则表达式的分组在java中是怎么使用的,start(),end(),group()均有一个重载方法它们是start(int i),end(int i),group(int i)专用于分组操作,Mathcer类还有一个groupCount()用于返回有多少组.
Pattern p=Pattern.compile("([a-z]+)(\\d+)");
Matcher m=p.matcher("aaa2223bb");
m.find(); //匹配aaa2223
m.groupCount(); //返回2,因为有2组
m.start(1); //返回0 返回第一组匹配到的子字符串在字符串中的索引号
m.start(2); //返回3
m.end(1); //返回3 返回第一组匹配到的子字符串的最后一个字符在字符串中的索引位置.
m.end(2); //返回7
m.group(1); //返回aaa,返回第一组匹配到的子字符串
m.group(2); //返回2223,返回第二组匹配到的子字符串
Pattern p=Pattern.compile("\\d+");
Matcher m=p.matcher("我的QQ是:456456 我的电话是:0532214 我的邮箱是:aaa123@aaa.com");
while(m.find()) {
System.out.println(m.group());
}
输出:
456456
0532214
123
如将以上while()循环替换成
while(m.find()) {
System.out.println(m.group());
System.out.print("start:"+m.start());
System.out.println(" end:"+m.end());
}
输出:
456456
start:6 end:12
0532214
start:19 end:26
123
start:36 end:39