注意: JAVA语法的字符串中 \\
才能起到 \
的作用
1. 基础不是语法,而是用法
先学会怎么开车,再去学如何修车和造车
java.util.regex类库中三大巨头:Pattern
、Matcher
、PatternSyntaxException
- Pattern类:Pattern是一个正则表达式的编译表示。
- Matcher类:Matcher是对输入字符串进行解释和匹配操作的引擎。
- PatternSyntaxException:PatternSyntaxException是一个非强制异常类,它表示一个正则表达式模式中的语法错误。
Pattern(模式)
Pattern类没有对外的构造方法,创建Pattern对象需要调用其静态方法compile
当你记住并理解我列出的下列方法,足矣
//compile有两个重载方法
/**
将给定的正则表达式编译到模式中
*/
public static Pattern compile(String regex)
/**
将给定的正则表达式编译到具有给定标志的模式中
*/
public static Pattern compile(String regex, int flags)
/**
Pattern实例与Matcher实例联系的桥梁
很重要的一个方法,将Pattern类与Matcher类联系起来,
Pattern类负责决定正则表达式能匹配的字符串
Matcher类能更强大、灵活的进行校验和其他操作
*/
public Matcher mathcer(CharSequence input)
/**
注意: 此方法名为 matchers(),直接放回true、false(比上面的方法多了一个s)
相当于直接调用Matcher的mathcers()方法(注意这三个方法的区别,两个输入Pattern,一个输入Matcher)
一步到位,直接返回匹配结果
Pattern.matchers(regex, input)
等价于
Pattern.compile(regex).matcher(input).matchers();
pattern实例 matcher实例 matcher方法
如果要多次使用一种模式,编译一次后重用此模式比每次都调用此方法效率更高
*/
public static boolean matchers(String regex, Charsequence input)
论正则式、Pattern、Matcher怎么配合工作的
一个正则表达式,首先编译
成为一个Pattern类的实例,这个Pattern实例会使用matcher()方法来生成一个Matcher实例(匹配器)。然后匹配器调用Matcher方法进行匹配工作。
Matcher(匹配器)
技能1 匹配(校验)
当你记住并理解我列出的下列方法,Matcher足矣
方法 | 说明 |
---|---|
boolean lookingAt() | 尝试从区域开始的输入序列与该模式匹配 |
boolean find() | 尝试查找与该模式匹配的输入序列的下一个 子序列 |
boolean find(int start) | 重置此匹配器,然后尝试查找匹配该模式、从指定索引开始的输入序列的下一个子序列 |
boolean matchers() | 尝试整个区域与模式匹配 |
特别注意find()方法,此方法从匹配器区域的开头开始,如果该方法的前一次调用成功了并且从那时开始匹配器没有被重置,则从以前匹配操作没有匹配的第一个字符开始。 重置方法reset()
技能2 查找
matcher常用的三个状态:
- 最近成功匹配的开始索引
- 最近成功匹配结束索引
- 最近成功匹配的内容
知识点1 :这三个状态在最初是为未定义的,在匹配成功之前,查询任何部分都会抛出IllegalStateException异常,并且每个
成功的
匹配操作都会重新计算以上三个状态
方法 | 说明 |
---|---|
int start() | 返回以前匹配的初始索引 |
int start(int group) | 返回在以前的匹配操作期间,由给定组所捕获的子序列 的初始索引 |
int end() | 返回最后匹配字符之后的偏移量 |
int end(int group) | 返回在以前的匹配操作期间,由给定组所捕获子序列 的最后字符之后的偏移量 |
String group() | 返回前一个符合匹配条件的子序列 |
String group(int group) | 返回指定的符合匹配条件的子序列,demo出真知 |
知识点2 :正则表达式中以’()’标记的子表达式所匹配的内容就是一个分组(group).,利用groupCount()方法可以获取当前匹配的捕获组数,0表示整个模式,即
group(0)
等价于group()
技能3 替换 – 非重点,可略读
方法 | 说明 |
---|---|
String replaceAll(String replacement) | 先重置匹配器,然后匹配所有 的regex能匹配的表达式,然后使用replacement替换,并返回替换后的input |
String replaceAll(String replacement) | 先重置匹配器,然后匹配第一 的regex能匹配的表达式,然后使用replacement替换,并返回替换后的input |
Matcher appendReplacement(StringBuffer sb, String replacement) | 将本次匹配之前 到上次匹配子串之后 的字符串段以及替换后的字符串 添加到一个 StringBuffer 对象里 |
StringBuffer appendTail(StringBuffer sb) | 将最后一次匹配工作后剩余的字符串添加到一个 StringBuffer 对象里 |
replcatAll()与replaceFirst()会修改匹配器的状态
如果待替换内容replacement中包含\
或$
,可能会导致异常,使用静态方法quoteReplacement()
后,斜线 (’’) 和美元符号 (’$’) 将不具有任何特殊意义
2. 正则表达式基础
语法
众所周知
- 正则表达式:前文一直用regex代表的逻辑公式,以特定的字符组合组成“规则字符串”,这个字符串用来表达一种过滤逻辑。
- 普通字符:在正则表达式中还是原来的意思,即数字0-9、小写字母a-z、大写字母A-Z、所有标点符号、空格制表符等符号
元字符
:在正则表达式中具有特殊含义的专用符号
基础字符
符号 | 含义 | regex举例 | 说明 |
---|---|---|---|
| | 多种选择,逻辑或的意思 | “123|45” | 匹配 123或45 |
() | 分组,每个小括号可以看成一个分组 | “a(b)c” | 括号不影响匹配,相当于"abc",但"a(b)c"匹配成功后,groupCount()返回1,且group(1)方法能匹配分组1匹配的内容。而"abc"匹配成功后,groupCount()返回0 |
[] | 圈定一组内容,但只匹配一个字符,指定选择的范围 | “[abc]” | 只匹配一个字符,匹配a或b或c |
[^] | 指定一个范围,不能匹配这个单字符 | “[^abc] ” | 匹配一个字符,但是不能是a或b或c |
{} | 限制字符出现的次数 | “{n}” "{n,}" “n,m” | 匹配n次 至少匹配n次 匹配n到m次 |
\ | 转义字符,对于元字符 来说,使用\能够将匹配元字符本身 | “\” | 匹配 \ ,java中两个\才相当于正则式中一个\ | |
^ | 匹配的以特定字符串开头的内容 | “^ab” | 匹配以ab开头的字符串,联系三个匹配方法 |
$ | 匹配的以特定字符串结束的内容 | “ab$” | 匹配以ab结束的字符串,联系三个匹配方法 |
- | 连字符 | “[0-9]” | 匹配0到9中一个字符,没有[],就没什么特殊含义了 |
\s | 表示任意的一位空格,例如:\n、\t等 | ||
. | 匹配除\n 以外的任何单个字符 |
知识点3 :正则表达式匹配时以字符为单位,复杂的表达式等价于匹配 一位字符的规则 + 匹配 一位字符的规则 + …
简化写法
一目了然的写法 | 等价的写法 |
---|---|
{0,1} | ? |
{1,} | + |
{0,} | * |
[0-9] | \d |
[^0-9] | \D |
[a-zA-Z] | \w |
[^a-zA-Z] | \W |
捕获与非捕获 – 非重点,略读
表达式 | 描述 | 捕获或非捕获 |
---|---|---|
(regex) | 匹配的子表达式 | 捕获 |
(?<name>regex) | 命名的反向引用 | 捕获 |
(?:regex) | 匹配但不获取匹配结果 | 非捕获 |
— | — | — |
(?=regex) | 正向肯定预查,如"baidu(?=cn | com"),能匹配到baiducom或baiducn,不能匹配到baidunet |
``(?!=regex) | 正向否定预查,如"baidu(?!cn | com)",能匹配baidunet,但是匹配不到baiducn或baiducom |