1.正则表达式
1.简介
- 1.正则表达式(
Regular Expression):是由普通字符(a~z/1~9等)和特殊字符(元字符)组成的文本模式,用来描述和匹配字符串的特定模式 - 2.正则表达式的组件可以是
单个字符、字符集合、字符范围或这些组件的任意组合 - 3.正则表达式用于模式匹配和搜索文本,其提供了一种灵活且强大的方式来查找、替换、验证和提取文本数据
- 4.正则表达式可以应用于各种编程语言和文本处理工具中,且正则表达式
区分字母大小写
2.模式
1.字符匹配
- 1.
普通字符:按照字面含义进行匹配(字母、数字、空格等,如a将匹配到文本中的小写a字母) - 2.
元字符:具有特殊的含义字符,元字符可以分为以下类型
1.基本元字符
| 元字符 | 含义 | 实例 |
|---|
. | 匹配除换行符(\n、\r)之外的任何单个字符,如果想要匹配包括换行符\n在内的任何字符,可使用(.|\n)模式 | .可以匹配123的任意一个字符 |
| | 逻辑或运算符,用于指定多个模式的选择 | 1|3可以匹配123中的1或3 |
[ ] | 匹配该字符集合中的任意一个字符(各个字符之间是OR的关系,而不是AND的关系) | [abc]可以匹配abandoned中的a、b |
[^] | 匹配非该字符集合中的任意字符 | [^abc]可以匹配plan中的p、l、n |
- | 连字符,定义一个字符区间 | a-z表示从小写字母a到小写字母z,一般配合[ ]使用 |
[a-z] | 匹配指定范围内的任意字符,同一个字符集合里可以给出多个字符区间 | [1-9]可以匹配plan666中的6 |
[^a-z] | 匹配非指定范围内的任意字符 | [^a-z]可以匹配非小写字母中的数据 |
\ | 转义字符,将含有特殊含义的字符转为普通字符(包括自身) | \|将|逻辑或运算符转为普通字符匹配 |
- 注意
- 1.
A-z匹配从ASCII字符A到ASCII字符z的所有字母,这个模式一般不用,因为它还包含[和^等在ASCII字符表里排列在Z和a之间的字符 - 2.定义一个字符区间的时候,一定要避免让这个区间的尾字符小于它的首字符(例
[3-1]),这种区间没有意义而且往往会让整个模式失效 - 3.
-只有在[ ]中才是元字符,在字符集合以外的地方,-只是一个普通字符,只能与-本身相匹配,因此在正则表达式中-字符不需要被转义 - 4.
^作用于字符集合中的所有字符或字符区间,而不仅限于紧跟^字符后面的那一个字符或字符区间
2.量词元字符
| 元字符 | 含义 | 实例 |
|---|
? | 匹配前面的 字符/子表达式 零次或一次 | do(es)?可以匹配do或does,等价于{0,1} |
* | 匹配前面的 字符/子表达式 零次或多次 | zo*可以匹配z或zoo,等价于{0,} |
+ | 匹配前面的 字符/字符集合/子表达式 一次或多次,给一个 字符集合/子表达式 加上+后缀的时候,必须把+放在 字符集合/子表达式 的外面 | zo+可以匹配zo或zoo,等价于{1,} |
{n} | 匹配前面的 字符/子表达式 恰好 n 次 | o{2}可以匹配food中的oo |
{n,} | 匹配前面的 字符/子表达式 至少 n 次 | o{2,}可以匹配food中的oo |
{n,m} | 匹配前面的 字符/子表达式 至少 n 次且不超过 m 次 | o{1,3} 可以匹配foooood中的前三个 o |
*?、+?、{n,}?、{n,m}? | 对应量词的懒惰型版本,懒惰型版本量词在第一次匹配上时就会停止匹配 | o{1,3}? 匹配到foooood中的第一个 o就直接停止匹配 |
- 注意
- 1.一般来说在字符集合中使用像
.和+这样的元字符将被解释为普通字符,不需要转义,但转义了也没有坏处,[\w.]的使用效果与[\w\.]等效 - 2.
*和+是贪婪型元字符,其匹配行为是多多益善而不是适可而止,它们会尽可能地从一段文本的开头一直匹配到末尾,而不是碰到第一个匹配时就停止 - 3.如果不需要贪婪型时,可使用这些量词的懒惰型版本,其匹配尽可能少的字符,而非尽可能多地去匹配,懒惰型量词的写法是在贪婪型量词后面加上一个
?

3.位置元字符
| 元字符 | 含义 | 实例 |
|---|
^ | 匹配输入字符串的开始位置 | ^t只能匹配到test首位的t |
\A | 匹配输入字符串的开始位置 | 等同于^ |
$ | 匹配输入字符串的结束位置 | t$只能匹配到test末尾的t |
\z | 匹配输入字符串的结束位置 | 等同于$ |
\b | 匹配一个单词边界(开始位置[\b在前]和结束位置[\b在后]) | \bab只能匹配到abccab首位的ab;ab\b只能匹配到abccab末尾的ab |
\B | 匹配非单词边界(中间位置) | \Bab只能匹配到abcabcab中间和末尾的ab;ab\B只能匹配到abcabcab中间和首位的ab |

- 注意
- 1.
\b匹配的是字符之间的一个位置:一边是单词(能够被\w匹配的字母数字字符和下划线),另一边是其他内容(能够被\W匹配的字符) - 2.如果想匹配一个完整的单词,就必须在要匹配的文本的前后都加上
\b - 3.
^只有出现在字符集合([])中且紧跟在左方括号[的后面时,才表示排除该字符集合,如果出现在字符集合之外并位于模式的开头,^将匹配字符串的起始位置 - 4.有些元字符拥有多种用途,
^就是其中之一;只有当它出现在字符集合[]中且紧跟在[的后面时才表示排除该字符集合;如果出现在字符集合之外并位于模式的开头,^将匹配字符串的起始位置
4.特殊元字符
| 元字符 | 含义 | 实例 |
|---|
[\b] | 匹配(并删除)一个字符(Backspace键) | |
\c | 匹配一个控制字符(控制字符即ASCII的0到31,再加上ASCII的127) | |
\f | 匹配一个换页符,等价于\x0c和\cL | \f可以匹配ab123\fab中的\f |
\n | 匹配一个换行符,等价于\x0a和\cJ | \n可以匹配ab123\nab中的\n |
\r | 匹配一个回车符,等价于\x0d和\cM | \r可以匹配ab123\rab中的\r |
\s | 匹配任意一个空白字符,包括空格、制表符、换页符等,等价于[空格\f\n\r\t\v] | \s可以匹配ab123\sab中的\s |
\S | 匹配任意一个非空白字符,包括空格、制表符、换页符等,等价于[^\f\n\r\t\v] | \S可以匹配ab123\sab中的除了\s的所有内容 |
\t | 匹配一个制表符(Tab键),等价于\x09和\cI | \t可以匹配ab123\tab中的\t |
\v | 匹配一个垂直制表符,等价于\x0b和\cK | \v可以匹配ab123\vab中的\v |
\w | 匹配任意一个字母(大小写均可)、数字或下划线,等价于[A-Za-z0-9_] | \w可以匹配ab123ab_中的任意一个字符 |
\W | \w的反义,匹配任意一个非字母、数字或下划线,等价于 [^A-Za-z0-9_] | \W无法匹配ab123ab_中的任意一个字符 |
\d | 匹配任意一个数字字符,等价于[0-9] | \d可以匹配ab123ab中的1/2/3 |
\D | \d的反义,匹配任意一个非数字字符,等价于 [^0-9] | \D可以匹配ab123ab中的a/b |
\x | 匹配一个十六进制数字 | \x41可以匹配Ab123ab中的A |
\0 | 匹配一个八进制数字 | \0101可以匹配Ab123ab中的A |


- 注意
- 1.
ASCII可显示字符编号范围是32-126(0x20-0x7E),共95个字符 - 2.
ASCII控制字符的编号范围是0-31和127(0x00-0x1F和0x7F),共33个字符
5.反向引用和环视元字符
| 元字符 | 含义 | 实例 |
|---|
() | 定义一个子表达式并捕获匹配结果,通过\n可以获取对应的匹配结果 | [ ]+(\w+)[ ]+\1可以匹配This is a block of of text中的of of |
(?: ) | 定义一个子表达式但不捕获匹配结果 | [ ]+(\w+)[ ]+\1无法匹配This is a block of of text中的of of |
\n | 反向引用,用来对先前的子表达式进行引用,\1匹配第一个子表达式;\2匹配第二个子表达式,以此类推 | [ ]+(\w+)[ ]+\1可以匹配This is a block of of text中的of of |
?= | 肯定式向前查看 | .+(?=:)可以匹配http://www.forta.com/ \n https://mail.forta.com/ \n ftp://ftp.forta.com/中:前面的的http、https、ftp |
?<= | 肯定式向后查看 | (?<=\\$)[0-9.]+可以匹配ABC01: $23.45 \n HGG42: $5.31中的23.45、5.31 |
?! | 否定式向前查看 | 祖国(?!的花朵)可以匹配到我爱祖国,我是祖国的花朵中的非的花朵前面的祖国 |
? | 否定式向后查看 | \\b(?可以匹配I paid $30 for 100 apples,50 oranges, and 60 pears.I saved $5 on this order.中的100、50、60 |
?() | 条件( if then ) | Java不支持 |
?()| | 条件(if then else) | Java不支持 |
- 注意
- 1.
*、?、{2}只作用于紧挨着它的前一个字符或字符集合 - 2.划分子表达式的目的是为了将
多个字符视为单一的实体来使用,子表达式必须出现在字符()之间 - 3.
反向引用指实体引用的是先前的子表达式,可以把反向引用想象成变量,而\n则是引用对应的变量 - 4.反向引用只能用来引用括号里的子表达式,子表达式是按照其相对位置来引用的,同一个子表达式可以被多次引用,只需在用到的地方写出其反向引用形式即可
- 5.需要根据所使用的正则表达式实现修改反向引用指示符(
Java、JavaScript用户需要用$来代替\) - 6.调整文本格式时把文本分解成多个子表达式,这样可以更精细地控制文本
- 7.向前查看和向后查看其实是有返回结果的,只不过结果永远都是零长度字符串,因此环视操作有时也被称为零宽度匹配操作
- 8.任何子表达式都可以转换为向前查看表达式,只要在其之前加上一个
?=即可,在同一个搜索模式里可以使用多个向前查看表达式,出现的位置没有任何限制 - 9.向前查看模式的长度是可变的,其中可以包含
.和+等量词,所以非常灵活;向后查看模式则只能是固定长度,几乎所有的正则表达式实现都有此限制 - 10.向前查看和向后查看通常都是用来匹配文本,主要用于指定作为匹配结果返回的文本位置(指明所需匹配之前或之后的文本);这种用法被称为肯定式向前查看和肯定式向后查看,术语
肯定式是指要执行的是匹配操作 - 11.否定式向前查看会向前查看
不匹配指定模式的文本;否定式向后查看则向后查看不匹配指定模式的文本 - 12.一般来说凡是支持向前查看的正则表达式实现也都支持肯定式向前查看和否定式向前查看;类似的凡是支持向后查看的正则表达式实现也都支持肯定式向后查看和否定式向后查看
- 13.环视可以更精细地控制最终的返回结果,环视操作允许利用子表达式来指定文本匹配操作的发生位置,但同时又不会消耗匹配到的文本(不出现在最终的匹配结果里)
- 14.
反向引用条件仅在一个前面的子表达式得以匹配的情况下才允许使用另一个表达式
6.大小写转换元字符
| 元字符 | 含义 | 实例 |
|---|
\E | 结束\L或\U转换 | Java不支持 |
\I | 把下一个字符转为小写 | Java不支持 |
\L | 把后面的字符转换为小写,直到遇到 \E 为止 | Java不支持 |
\u | 把下一个字符转换为大写 | Java不支持 |
\U | 把后面的字符转换为大写,直到遇见 \E 为止 | Java不支持 |

- 注意
- 1.
\l和\u可以放置在字符/子表达式之前,转换下一个字符的大小写,\L和\U可以转换其与\E之间所有字符的大小写
7.POSIX字符类

- 注意
- 1.
POSIX字符类必须出现在[:和:]之间,因为使用的POSIX字符类是[:xdigit:]而不是:xdigit: - 2.如果和字符集合连用,则外层的
[和]字符用来定义一个字符集合,内层的[和]字符是POSIX字符类本身的组成部分
8.匹配模式
| 元字符 | 含义 | 实例 |
|---|
(?m) | 多行模式,多行模式迫使正则表达式引擎将换行符视为字符串分隔符 | (?m)^\\s*\\/\\/.*$可以匹配test\n//Make sure not empty 中的注解内容 |
- 注意
- 1.
^和$通常分别匹配字符串的首尾位置,但通过(?m)模式可以迫使正则表达式引擎将换行符视为字符串分隔符 - 2.此时
^既可以匹配字符串开头,也可以匹配换行符之后\n的起始位置(新行);$不仅能匹配字符串结尾,还能匹配换行符之后的结束位置 - 3.使用时
(?m)必须出现在整个模式的最前面,包括JavaScript在内的许多正则表达式实现不支持(?m) - 4.有些正则表达式实现支持使用
\A标记字符串的开头,使用\Z标记字符串的结尾;此时\A和\Z的作用基本等价于^和$,但注意不像^和$,\A和\Z不会因为(?m)修饰符而改变行为,所以不能用于多行模式
2.常用案例
1.字符
^[\u4e00-\u9fa5]{0,}$
^[A-Za-z0-9]+$
^[\u4E00-\u9FA5A-Za-z0-9_]+$
2.数字
^[0-9]*$
^\d{n}$
^\d{n,}$
^\d{m,n}$
^(0|[1-9][0-9]*)$
^([1-9][0-9]*)+(\.[0-9]{1,2})?$
^(\-)?\d+(\.\d{1,2})$
^(\-|\+)?\d+(\.\d+)?$
^[0-9]+(\.[0-9]{2})?$
^[1-9]\d*$
或
^([1-9][0-9]*){1,3}$
或
^\+?[1-9][0-9]*$
^\-[1-9][]0-9"*$
或
^-[1-9]\d*$
^\d+$
或
^[1-9]\d*|0$
^-[1-9]\d*|0$
或
^((-\d+)|(0+))$
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
3.地址+域名+URL+号码
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
((?:(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d)\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d?\\d))
[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?
https?:\/\/[-\w.]+(:\d+)?(\/([\w\/_.]*)?)?
https?:\/\/(\w*:\w*@)?[-\w.]+(:\d+)?(\/([\w\/_.]*(\?\S+)?)?)?
(\d{3}-|\d{4}-)?(\d{8}|\d{7})?
[1-9][0-9]{4,}
[1-9]\d{5}(?!\d)
4.日期+身份证
^(d{2}|d{4})-((0([1-9]{1}))|(1[1|2]))-(([0-2]([1-9]{1}))|(3[0|1]))$
^((0([1-9]{1}))|(1[1|2]))/(([0-2]([1-9]{1}))|(3[0|1]))/(d{2}|d{4})$
^\d{4}-\d{1,2}-\d{1,2}
(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)
5.账号+密码
^[a-zA-Z][a-zA-Z0-9_]{4,15}$
^[a-zA-Z]\w{5,17}$
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])[a-zA-Z0-9]{8,10}$
^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$
3.Java正则表达式
- 1.
Java中的正则表达式匹配功能是通过java.util.regex.Matcher、java.util.regex.Pattern类和以下方法实现 - 2.注意
- 1.不支持嵌入条件
- 2.不支持使用
\E、\l、\L、\u和\U进行大小写转换 - 3.不支持使用
\b匹配退格符 - 4.不支持
\z
1.compile()
2.matches()
3.find()
4.lookingAt()
5.replaceAll()
6.replaceFirst()
7.flags()
8.flags()
9.split()
4.代码
@Data
public class PatternData {
private String data;
private String pattern;
private String replaceData;
}
@PostMapping("/matchStr")
public String getMatchStr(@RequestBody PatternData patternData){
Pattern r = Pattern.compile(patternData.getPattern());
Matcher m = r.matcher(patternData.getData());
StringBuilder str = new StringBuilder();
String replaceData = patternData.getReplaceData();
while(m.find()){
System.out.println("=========");
int start = m.start();
int end = m.end();
String tempStr = "index:" + start + "~" + end +",\t text:" + m.group(0);
System.out.println(tempStr);
str.append(tempStr).append("\n");
}
String s = m.replaceAll(replaceData);
str.append("replace: " + s);
return str.toString();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31