书本《正则指引》,示例语言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不支持)五、其他
- 表达式优先级
()* ? +abca|b- 各语言匹配的默认编码
- NE、Python 3T默认采用Unicode匹配规则,但可以显式指定采用ASCII匹配规则
- Java、js、php 默认采用ASCII匹配规则
-
[\u4e00-\u9fa5]可以仅匹配中文 -
[^\x00-\xff]匹配所有全角符号,包含汉字和全角标点
-
.*、(…*)*虽然可以匹配但回朔多,造成慢和损耗性能