正则表达式 https://reg.coderead.cn/?u_dit=blili2#/course/regex
正则表达式
常用符号
.任意字符 除换行符外的任意单个字符 添加s修饰符,可以让.包括换行符
\w 单词字符 字母、数字、下划线任意单个字符。大写\W 表示非单词字符 在python \w还可以表示汉字
\d 数字 0-9任意单个数字。大写\D 表示非数字
\s 空白字符 空格、tab制表符、换行都属于空白字符。大写\S 非空白字符,可以用[\s\S]表示任意字符
[abc123] 任意范围 |
一组由确定字符组成的字符集,取其中一个 |
|
[0-9] 数字区间范围 |
指定数字范围集,[0-9] 等同于\d |
|
[a-z] 字母区间范围 |
指定字母范围集。 |
|
[\d\w\s] 固定范围集 |
由多个固定范围集,组成一个更大的集 |
|
[0-9A-F\s] 混合集 |
上述四个自定义混合组成的集 |
|
[^ ] 排除范围 |
表示[ ]集之外的任单个字符,如[^0-9] 表示非数字,效果等同于\D |
|
|的转义
1.如果要匹配 | 本身,需要进行转义,如:\| 表示匹配 | 符号,或者放在自定义范围集中[|]也可以有同样效果。
2.由于 | 在类Unix系统中是特殊字符,当你使用grep或 vim 进行正则搜索时,必须进行转义。如grep中正则搜索正确姿势是:
grep '401\|403\|404\|500' nginx.access.log
3.在vim 中输入/ 开始正则搜索,同样|需要转义
/401\|403\|\404|\500
{}量词的使用
{n} 指定数量 |
匹配n个字符 |
|
{n,m} 指定范围 |
匹配n至m个字符,即至少n个,最多m个。 |
|
{n,} n个及以上 |
匹配n个或者n个以上字符 |
|
* 任意个 |
相当于{0,} 0个或无数个 |
|
+ 至少1个 |
相当于 {1,} |
|
? 0或1个 |
相当于 {0,1} |
|
? 最少化匹配(懒惰匹配):只能用在量词后面,表示如果多个文本段同时满足条件,则匹配最短的。?可以用在所有量词后面,甚至是?? ,但这个量词不能是固定的值,如:hel{2}?o 这是没有意义的。因为它不存在最少和最多。
正则分组
(\d{4})-(\d{2})-(\d{2})
// java
public static void main(String[] args) {
Pattern pattern=Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher matcher = pattern.matcher("小丽生日是2011-11-23");
if (matcher.find()) {
String month = matcher.group(2);// 获取第2组中的月份
System.out.println("月份是:"+month);
}
}
// 输出如下结果:
"月份是:11"
反相引用
<h1>一级标题</h1>
<h2>二级标题</h2>
<h2>三级标题</h3>
<(h[1-6])>.*?<\/\1> 步骤拆解如下:
<(h[1-6])> 匹配开始标签,并把标签名加入分组1
.*? 标签中间可以是任意内容。
<\/\1> 匹配结束标签,标签内容通过\1引用分组1(意思是与分组1的内容一致)
替换
替换操作指将正则匹配到的内容,替换成指定字符串,该字符串可通过$组号引用组进行拼装。通过$0可以引用整个匹配的内容。比如:日期“1960/02/19”被匹配之后 $0表示整个日期,$1、$2、$3 分别表示年月日。请注意反向引用与替换引用的语法区别,前者是使用\组号,而替换使用$组号。
$0在 Python与Javascript中不支持,使用$&代替
大小写转换
| \u 单个转大写 |
转换一下个字符为大写 |
|
| \U 全部转大写 |
转换\U后所有字符转大写 |
|
| \U...\E 区间转大写 |
\U与\E区间的内容转大写 |
|
| \l 单个转小写 |
转换一下个字符为小写 |
|
| \L 全部转小写 |
转换\L后所有字符转小写 |
|
| \L...\E 区间转小写 |
\L与\U区间的内容转小写 |
|
编写匹配正则:\w+
首字母转大写并替换:\u$0
"my love" 被替换后结果就是"My Love"
其他应用
(?<名称> )命名分组
(?: ) 移除分组
( ( ) )嵌套分组
()+分组使用量词
边界断言
(?= ) 前置断言 (?<= ) 后置断言
(?<=身高)\d{3}(?=cm)
曾小红,男、编号007,举重运动员,28岁,体重56KG,身高175cm,腰围110cm。最好成绩:挺举98KG
只匹配175
(?= ...) 前置断言 |
判定一段表达式前面是否满足条件 |
|
(?! ...) 前置否定断言 |
判定一段表达式前面是否不满足条件 |
|
(?<= ...) 后置断言 |
判定一段表达式后面是否满足条件 |
js中部分浏览器不支持 |
(?<! ...) 后置否定断言 |
判定一段表达式后面是否不满足条件 |
js中部分浏览器不支持 |
高级特性
- 零宽断言:断言条件本身不会消耗字符 断言的内容不会被消耗仍可以作为下次匹配内容
- 多边界断言:一个正则可同时存在多个边界断言。根据其所处位置来决定断言的边界。
- 条件组合:多个子断言可以进行布尔运算如:
&& || ()
h(?=条件1)(?=条件2) 且运算,指必须同时满足多个条件
h(?=(?=条件1)(?=条件2)) 且运算,条件1与条件2组成一个新条件,并且两个条件都必须满足
h(?=(?=条件1)|(?!条件2)) 或运算,满足条件1或者 不满足 条件2
h(?=表达式1|(?=条件1)(?!条件2)) 混合运算,表示满足表达式1或者同时满足条件1、2
- 任意边界:可以是任意合法的表达式边界,甚至可以是空字符边界。
验证长度:(?=^.{8,20}$),表示总字符长度在8至20之间。^ $ 是两个特殊字符,这里分别表示文本的开头与结尾,将在后续章节专门学习。
验证大写字母:(?=.*[A-Z]),表示文中任意地方至少出现一次大写字母。
验证小写字母:(?=.*[a-z]),表示文中任意地方至少出现一次小写字母。
验证数字:(?=.*\d),表示文中任意地方至少出现一次数字。
最后组合条件并追加内容 (?=^.{8,20}$)(?=.*[A-Z])(?=.*[a-z])(?=.*[\d]).+
特殊边界断言
^ 文本开头 |
默认情况下,表示断言文本开头 |
|
$文本结尾 |
默认情况下,表示断言文本结尾 |
|
^ 行开头 |
被m修饰后,^表示行的开头,等价于`(?<=\n |
\A)` |
$ 行结尾 |
被m修饰后,$表示行的结尾,等价于`(?=\n |
\Z)` |
\A 文本开头 |
断言文本开头 |
Javascript 不支持 |
\Z 文本结尾 |
断言文本结尾 |
Javascript 不支持 |
\b单词开头或结尾 |
断言单词开头或结尾 |
|
\B |
\b 否定式,非单词开头或结尾 ,等价于(?<!\b) 或(?!\b) |
|
多行时就得看有没有用行边界修饰符m
修饰符
global 全局匹配 |
默认只返回匹配到的第一个结果,加上g匹配全部可匹配结果 |
|
insensitive 勿略大小写 |
不区分大小写 |
|
multi line 行边界修饰符 |
此模式下^和$可以分别匹配行首和行尾,默认情况下只能匹配文本开头与结尾 |
|
single line . 通配修饰符 |
此模式下.能匹配任意字符,包括换行符 |
|
extended 注释修饰符 |
忽略空白字符,可以多行书写,并使用#进行注释说明 |
javasc |
/<span>.*?<\/span>/gimse
常见用例
/\b\w+ll\b/gm 匹配以ll结尾的单词
/^\n|^\s+$\n/gm 删除所有空白行
/^\s*#.*\n|^\n|^\s+$\n/gm 删除所有#注释及空白行
/(?!^)(?=(\d{3})+$)/gm 添加千分位