java正则表达式
什么是正则表达式
正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。(来源:百度百科)
java中如何使用正则表达式
java中使用正则表达式要分五步走
- 准备欲匹配的正则表达式
- 创建正则表达式对象
- 创建匹配器
- 遍历表达式
- 获取匹配结果
demo:
public class RegTheory {
public static void main(String[] args) {
String content = "1998年12月8日,第二代Java平台的企业版J2EE发布。1999年6月,Sun公司发布了第二代Java平台(简称为Java2)的3个版本:J2ME(Java2 Micro Edition,Java2平台的微型版),应用于移动、无线及有限资源的环境;J2SE(Java 2 Standard Edition,Java 2平台的标准版),应用于桌面环境;J2EE(Java 2Enterprise Edition,Java 2平台的企业版),应用于基于Java的应用服务器。Java 2平台的发布,是Java发展过程中最重要的一个里程碑,标志着Java的应用开始普及。";
// \\d表示0-9的任意数字
String regStr = "(\\d\\d)(\\d\\d)";
//创建正则表达式对象
Pattern compile = Pattern.compile(regStr);
//创建匹配器
Matcher matcher = compile.matcher(content);
/**
* matcher.find()
* 1、根据指定的规则定位满足规则的子字符串(比如1998)
* 2、找到后将字符串开始索引记录到属性group中
* 3、把结束索引+1记录到group中
* 4、同时记录oldLast值为结束索引+1(下次在寻找的位置)
* match.group();
*
* public String group(int group) {
* if (first < 0)
* throw new IllegalStateException("No match found");
* if (group < 0 || group > groupCount())
* throw new IndexOutOfBoundsException("No group " + group);
* if ((groups[group*2] == -1) || (groups[group*2+1] == -1))
* return null;
* return getSubSequence(groups[group * 2], groups[group * 2 + 1]).toString();
* }
* 1、根据group【0】到group【1】进行记录的位置进行截取,从content开始截取子字符串并返回
*/
//遍历表达式
while (matcher.find()){
//输出结果
System.out.println(matcher.group(0));
}
}
}
结果
1998
1999
Process finished with exit code 0
正则表达式语法
转义符:(两个斜杠)\\
标记某些特殊字符,使之成为可以被正常处理的字符串。
转义字符是很多程序语言、数据格式和通信协议的形式文法的一部分。
需要用到的转义符如下:
. * + ( ) $ / \ ? [ ] ^ { }
正则匹配字符
聚合符
符号 | 释义 | 示例 | 解释 |
---|---|---|---|
[ ] | 可接受的字符串列表 | [abcd] | 接收abcd中的任意一个字符 |
[^] | 不可接收的字符串列表 | [^efg] | 接收除efg以外的任何一个字符 |
- | 连字符 | A-Z | 任意一个大写字母 |
匹配符
符号 | 释义 | 示例 | 解释 | 匹配结果 |
---|---|---|---|---|
. | 匹配除\n以外的其他字符 | a…b | 以a开头,b结尾的任意4位字符串 | aaab,abbb,accb,a**b |
\d | 匹配单个数字,例如0-9 | \d{3}{\d}? | 包含3-4个数字的字符串 | 123,1234 |
\D | 匹配非单个数字 | \D{\d}* | 以非数字开头,后面接任意数字 | a,a123 |
\\w | 匹配单个数字或大小写字母 | \d{3}\\w{4} | 以三个字母开头的长度为7的数字字母字符串 | 234bacd,12345b7 |
\\W | 匹配单个非数字、非大小写字母 | \\W+\d{2} | 以至少一个非数字字母开头两个数字字符结尾的字符串 | #22,#@#10 |
\\s | 匹配单个空字符串 | \d{2}\\s\d{2} | 两个数字中间空格 | 11 22 |
\\S | 匹配非单个空字符串 | \d{2}\\S\d{2} | 两个数字中间无空格 | 11322 |
限定符
符号 | 含义 | 实例 | 说明 | 匹配输入 |
---|---|---|---|---|
* | 重复0到多次 | (abc)* | 包含多个abc字符串 | abc,abcabc |
+ | 重复一或多次 | m+(abc)* | 至少一个m开头,0或多个abc结尾 | m,mmmabcabc |
? | 重复0或1次 | m+abc? | 至少一个m开头,以ab或abc结尾 |
定位符
符号 | 含义 | 示例 | 说明 | 匹配 |
---|---|---|---|---|
^ | 起始字符 | ^ [0-9]+[a-z]* | 至少一个数字开头,后面接任意个小写字母的字符串 | 123,6ss,333sd |
$ | 结束字符 | ^ [0-9]+[a-z]$ | 至少一个数字开头,一个小写字母结束的字符串 | 1a |
\b | 目标字符串的边界 | cd\b | 结束位置有空格 | abcd efcdg |
\B | 目标字符串非边界 | cd\b | 结束位置无空格 | abcd efcdg |
小括号:
表示可以匹配的字符串,例如(abc)则表述匹配的字符串"abc",(a-c)表述只可以字符串“a-c”,可以通过(a|b|c)表述匹配字符“a”,“b”,“c”。
中括号:
表示匹配字符出现的范围,例如[abcd]则表示匹配字符a,b,c,d的任意一个,,其等同于[a-d],也等同于(a|b|c|d)。
注意,在[ ]中,| 出现会被认定为符号“|”进行匹配。
大括号:
表示匹配出现的次数,{n}出现n次,{n,}出现至少n次,{n,m}最少出现n次,最多出现m次。
大小写
创建Pattern时增加参数Pattern.CASE_INSENSITIVE:
public class RegExp3 {
public static void main(String[] args) {
String context = "abcABCaBcAbC";
String regStr = "abc";
Pattern compile = Pattern.compile(regStr,Pattern.CASE_INSENSITIVE);
Matcher matcher = compile.matcher(context);
while (matcher.find()){
System.out.println(matcher.group(0));
}
}
}
贪婪与懒惰
贪婪匹配:
当{m,n}时,尽量匹配到n
当x+ / x*时,尽量匹配到最大值
这就是贪婪匹配
demo:
public class RegExp7 {
public static void main(String[] args) {
String content = "1111111";
String regStr = "\\d{2,3}";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println(matcher.group());
}
}
}
111
111
懒惰匹配:
在修饰数量的值(*,+,{m,n})后面加一个?,即形成贪婪匹配:
demo:
public class RegExp7 {
public static void main(String[] args) {
String content = "1111111";
String regStr = "\\d{2,3}?";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println(matcher.group());
}
}
}
输出结果:
11
11
11
分组
一个()内为一个分组
顺序按照左括号从左到右排序
使用matcher.group(n)对第n个分组进行获取。
demo:
public class RegExp4 {
public static void main(String[] args) {
String content = "huangshiping s77872 nn2213han";
String regStr = "(\\d(\\d))(\\d\\d)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println(matcher.group(0));
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
System.out.println(matcher.group(3));
}
}
}
执行结果:
7787
77
7
87
2213
22
2
13
命名分组
可以通过对分组进行命名来获取分组:
demo:
public class RegExp4 {
public static void main(String[] args) {
String content = "huangshiping s77872 nn2213han";
// 命名分组
String regStr = "(?<g1>\\d(\\d))(\\d\\d)";
Pattern pattern = Pattern.compile(regStr);
Matcher matcher = pattern.matcher(content);
while (matcher.find()){
System.out.println("g1:"+matcher.group("g1"));
}
}
}
执行结果:
g1:77
g1:22
非拼接捕获
非拼接捕获用于快速生成表达式
content = “jerry老师 jerry同学 jerry教授”;
符号 | 过滤器 | 输出结果效果(加粗为打印结果) |
---|---|---|
?: | jerry(?:老师|同学) | jerry老师 jerry同学 jerry教授 |
?= | jerry(?=老师|同学) | jerry老师 jerry同学 jerry教授 |
?! | jerry(?!老师|同学) | jerry老师 jerry同学 jerry教授 |
Pattern常用方法
matches整体匹配
public class PatternTest {
public static void main(String[] args) {
String content = "在现实的产品设计场景中";
String regStr = "在.*";
boolean matches = Pattern.matches(regStr,content);
System.out.println(matches);
}
}
true
public class PatternTest {
public static void main(String[] args) {
String content = "在现实的产品设计场景中";
String regStr = "在";
boolean matches = Pattern.matches(regStr,content);
System.out.println(matches);
}
}
false