书本《正则指引》,示例语言python
。
一、字符
-
[...]
的形式指字符组,用于匹配指定字符。 -
[x-y]
的形式指范围表示法,例:[0-9]
表示[0123456789]
- 范围的本质是字符在ASCII中的码值从小到大的排序
- 可以并列多个范围表示法,例:
[0-9a-zA-Z]
- 字符可以用
\xhex
的形式表示(可以匹配中文字符),\x
固定值,hex
指字符对应码值,例:\x41
表示字母A
[
、]
、-
、^
、$
等等。- 字符
-
如果紧邻[
或[^
表示字符,其他情况是元字符,例:[-09]
表示“-09”三个字符,而非“0123456789”十个字符 - 用
\
可以转义元字符为普通字符,但写在""
引号之间时要用\\
,例:只匹配有3个字符的字符串0-9
,需要这样写regStr = "[0\\-9]"
[^...]
的形式指排除当前范围。\d
、\w
、\s
、\D
、\W
、\S
。-
\d
指[0-9]
匹配数字 -
\w
指[0-9a-zA-Z_]
匹配单词 -
\s
指[ \t\r\n\v\f]
(第一个是空格)匹配空白字符 - 大写
\D
、\W
、\S
指上面三个的排除 -
.
匹配除\n
之外的任何单个字符 - 可以使用
[\s\S]
、[\d\D]
或[\w\W]
来匹配任意字符
- java中
[[a-z]&&[^aeiou]]
- .net中
[a-z-[aeiou]]
[:digit:]
、[:lower:]
。二、量词
- 量词的基本形式
-
{m,n}
之前的元素最少出现m
次,最多出现n
次 -
{n}
之前的元素必须出现n
次 -
{m,}
之前的元素必须出现m
次,最多无上限 -
{0,n}
之前的元素可以出现或不出现,最多出现n
次
-
+
等价于{1,}
-
?
等价于{0,1}
-
*
等价于{0,}
- 基本量词形式字符串在开头加
\
即可,例:要匹配字符串“{m,n}”必须写成\{m,n}
- 其他常用量词形式直接加
\
即可,例:\+
、\?
、\*
三、括号
-
(...)
形式叫做分组 -
(...|...)
形式叫做多选分支,可以分割多个子表达式,数目无限制。
- 多选结构也可以没有
()
括号(不推荐),例:ab|cd
等价于(ab|cd)
- 多选结构每个分支必须明确写出,不能使用
-
范围法
()
括号后,正则表达式会保存每个分组匹配的文本,待匹配完成后返回。- 可以使用
group(num)
方法获取,num
指分组编号 - 规则是:从左向右按照开括号出现的顺序计数
-
1
开始,编号为0
的分组是默认存在的
\num
。例:检测字符串“deep”是否含有叠词,表达式为([a-z])\1
,其中[a-z]
匹配第一个字母\1
表示反向引用之前匹配的字母。re.sub(pattern,replacement,string)
其中replacement
待替换字符可以引用分组,形式是\num
(num
是分组编号,\num
在字符串中是非合法转义序列,所以非原生字符串需\\num
才有效)。例:替换字符串“2023-03-23”为“2023年3月23日”,表达式为re.sub(r"(\d{4})-(\d{2})-(\d{2})",r"\1年\2月\3日","2023-03-23")
-
.net
:表达式中\num
,替换的字符串中$num
-
java
:表达式中\num
,替换的字符串中$num
-
js
:表达式中$num
,替换的字符串中$num
-
php
:表达式中\num
,替换的字符串中$num或\num
-
python
:表达式中\num
,替换的字符串中\num
-
ruby
:表达式中\num
,替换的字符串中\num
\10
中的0
会出现两种意义(匹配规则默认是第10个分组,但我只想引用第1个,后面这个0
是独立的)。精确标注:-
python
中使用\g<1>0
-
php
中使用\${1}0
- 其他语言会自动判断,但也无解,引用分组不要超过9个就行
\num
数字不直观和2义性,各语言差异-
.net
:分组(?<name>...)
,表达式中\k<name>
,替换的字符串中${name}
-
java7+
:分组(?<name>...)
,表达式中\k<name>
,替换的字符串中${name}
-
js
:不支持 -
php
:分组(?P<name>...)
,表达式中(?P=name)
,替换的字符串中不支持
-
python
:分组(?P<name>...)
,表达式中(?P=name)
,替换的字符串中\g<name>
-
ruby
:分组(?<name>...)
,表达式中\k<name>
,替换的字符串中\k<name>
(?:...)
,匹配但捕获,可以提高运行时性能。-
apache
和nginx
的替换规则为$num
-
iis
的替换规则为{R:num}
三、断言
不真正匹配文本,而只负责判断在某个位置左/右侧的文本是否符合要求,这种结构被称为断言。
-
\b
用于匹配单词边界,也就是指单词和空格间的位置 - 行起始/结束位置
-
^
用于匹配行的开头位置,例:字符串“first line\nsecond line\r\nlast line”,多行模式下,行开头可以匹配到3个 -
\A
(js不支持)用于匹配整个字符串开头,不管有没有行。 -
$
用于匹配行的结束位置,包含\n
换行符的情况 -
\z
(python是\Z
,js不支持)用于匹配行的结束位置,不包含\n
换行符的情况 -
^
和$
进行正则表达式替换时并不会被替换,只会在起始/结束位置添加一些字符,位置本身仍然存在
-
(?!...)
当前位置之后不允许出现某个字符,例:A(?!abc)
指字母A后不能出现字符串abc -
(?<!...)
当前位置之前不允许出现某个字符 -
(?=...)
当前位置之后必须出现某个字符 -
(?<=...)
当前位置之前必须出现某个字符
四、匹配模式
-
(?模式1模式N)
用于指定匹配模式,js
除外。如果写在表达式中表示从当前位置开始
-
(?i)
用于指定匹配小写,例如:re.search(r"(?i)the","The")
-
(?s)
用于匹配单行模式,行指换行符 -
(?m)
用于匹配多行模式 -
(?x)
用于注释模式,可以在表达式内部夸多行对表达式进行解释。(?#...)
这种形式注释在java和js中无效
(?-模式1模式N)
用于结束匹配模式((?模式)...)...
中,则作用范围就在括号内(python不支持)五、其他
- 表达式优先级
()
* ? +
abc
a|b
- 各语言匹配的默认编码
- NE、Python 3T默认采用Unicode匹配规则,但可以显式指定采用ASCII匹配规则
- Java、js、php 默认采用ASCII匹配规则
-
[\u4e00-\u9fa5]
可以仅匹配中文 -
[^\x00-\xff]
匹配所有全角符号,包含汉字和全角标点
-
.*
、(…*)*
虽然可以匹配但回朔多,造成慢和损耗性能