什么是正则表达式

正则表达式,英文名Regular Expression,常见缩写regex、regexp或RE都指代正则表达式。

正则表达式是对句法规定的一种形容。正则表达式应用单个字符串来形容、匹配一系列匹配某个句法规定的字符串。

正则表达式是由一些根本的汇合及对汇合的运算组成的。

根本元素

一般字符 字母、数字、汉字、下划线、以及后边章节中没有非凡定义的标点符号,都是"一般字符"。表达式中的一般字符,在匹配一个字符串的时候,匹配与之雷同的一个字符。

举例:

表达式 "c",在匹配字符串 "abcde" 时,匹配后果是:胜利;匹配到的内容是:"c",匹配到的地位是:开始于2,完结于3。(注:下标从0开始还是从1开始,因以后编程语言的不同而可能不同)

根本运算

交加

如果有两个正则表达式E和F,那么EF也是一个正则,示意同时匹配E和F的内容。这跟编程中的逻辑与是一个意思,跟汇合中的交加也是一个意思。你也能够连贯任意多个正则。

举例:

表达式 "bc",在匹配字符串 "abcde" 时,匹配后果是:胜利;匹配到的内容是:"bc",匹配到的地位是:开始于1,完结于3。

并集

如果有两个正则表达式E和F,那么E|F也是一个正则,示意匹配E或者匹配F。这跟编程中的逻辑或是一个意思,跟汇合中的并集也是一个意思。 你能够应用|连贯任意多个正则表达式。

如果你要连贯十分多的正则,那就得写十分多的竖线,看起来十分乱。所以人们还约定了一种简化记法[EFGH],跟写成E|F|G|H成果是一样,但前者更简短,更清晰。

举例:

表达式 " [bcd][bcd] " 匹配 "abc123" 时,匹配的后果是:胜利;匹配到的内容是:"bc";匹配到的地位是:开始于1,完结于3。

补集

如果你要排除匹配E和F的内容,须要写成 [ ^EF ]

举例:

表达式 "[^abc]" 匹配 "abc123" 时,匹配的后果是:胜利;匹配到的内容是:"1";匹配到的地位是:开始于3,完结于4。

单元素汇合

连字符示意多个元素

一个字母a, 一个数字1都是正则,别离匹配蕴含a和蕴含1的内容。

如果咱们想匹配数字1234,那么依据交加规定,咱们写成1234就能够了。

如果咱们想匹配所有可能呈现的数字,则能够依据并集规定写成0|1|2|3|4|5|6|7|8|9。是不有点长。咱们能够简化成[0123456789]。一下子少了很多坚线。

慢着,如果想匹配所有可能呈现的小写字母呢?难不成要将26个字母全副写入正则表达式中?

正则表达式为此提供了一种更加简化办法——连字符,能够应用减号-示意间断呈现的字符,只需写出头尾。所以咱们能够把[0123456789]进一步简化成[0-9],把[abc...xyz]简化成[a-z]。

\d

因为[0-9]很罕用,大家又进一步简化成了\d(对应单词 digit)。

\a

因为[a-zA-Z]也很罕用,大家就把它简化成\a(对应单词 alpha)。

\w

果想匹配大小写字母、数字和下划线(也就是所有单词字符),能够写成[a-zA-Z0-9_]。也是因为太罕用,大家将其简化为\w(对应单词 word)。

\s

如果想匹配一些空白字符,能够写成[ \t\r\n\v\f],这个正则会匹配空格、程度制表符、回车、换行、 垂直制表符和 Page break 记。这里用到了跟 c 语言 printf 函数一样的转义字符。同样因为应用宽泛,被简化为\s(对应单词 space)。

取反——大写

正则反对取反操作。[0-9]示意匹配所有数字,那[ ^0-9 ]就示意匹配所有非数字字符。因为应用宽泛,人们将其简写成\D。大家留神,[0-9]简写成\d(小写字母),对应的[ ^0-9 ]简写成\D(大写字母)。以此类推,\a取反是\A、\w取反是\W、\s取反是\S。

选集

有了连字符和并集规定,实践上咱们能够匹配所有字符。然而 Unicode 有上百万字符,难道咱们都要写到方括号里吗?不可能。

咱们能够利用取反操作。只有排除大量不罕用字符,就能够匹配剩下的大多数字符了。但排除哪个呢?最终人们决定排除\n。为什么呢?因为一般而言,正则都是逐行匹配的,一次匹配一行内容,不会遇到换行符。最终能够用[ ^\n ]示意匹配所有字符。同样因为太罕用,这一写法被简化成句点'.'。 也就是说在正则表达式中,一个.能够匹配\n以外的所有字符。

转义字符\

多元素汇合

大括号示意一次匹配多个元素

如果想匹配两位数字,能够利用交加规定,写成\d\d,此正则会先匹配一个数字再匹配一个数字,最终匹配的是两位数字。如果想匹配三位数字,须要写成\d\d\d,四位数字写成\d\d\d\d。

那如果想匹配一位或者两位数字或者三位数字或者四位数字(也就是四位以内的数字),须要写成

\d|\d\d|\d\d\d|\d\d\d\d
有点长,然而 it works!如果想匹配所有的八位以内的数字呢?那就得写很长很长了。为此,人们又想了个简化的方法。这次引入了大括号{}。

方才的正则是能够简化成\d{1,4},开展就是\d|\d\d|\d\d\d|\d\d\d\d。大括号中第一个数字示意最短匹配的次数,第二个数字示意最长匹配的次数。

如果想匹配八位以内的数字,就能够写成\d{1,8},是不是很简洁呢?

如果只想匹配一个八位数,则能够写成\d{8,8}。反复写两个8如同有点多余,还是简化成\d{8}吧。

+号

那能不能匹配任意长度的数字呢? 实践上应该写成\d{1,∞},只是这个∞不好写,罗唆省略,写成\d{1,}算了。所以\d{1,}示意能够匹配一位、两位、始终到任意长度的数字。也就是说{1,}示意后面的匹配内容至多呈现一次。因为这个至多呈现一次也是特地罕用,人们又进一步将其简化成+,最终咱们的正则变成了\d+,优雅的不行。

*号

那能不能实现匹配呈现零次这种语义呢? 能够,只有将大括号内第一个数字写成0就行。所以a{0,}能够匹配a、aa……aaaa……等各种状况。也就是说{0,}示意后面的匹配的内容呈现屡次或者不呈现。 同样非常罕用,被人们简化成了。所以原来的正则能够简化成a

?号

最初就是{0,1}这种状况了,显然示意呈现零次或者一次。 不用说,懒人们将其简化成了?。所以ab?只能匹配a和ab两种状况。

一些常见的用法

贪心与非贪心模式

正则表达式默认应用贪婪模式,退出?改为非贪心模式

常见的用法有

.*为贪心匹配,从最长字符串开始匹配,可回溯.*?为非贪心匹配,具备最小匹配性质

例如:
<img src="test.jpg" width="60px" height="80px"/>

用表达式src=".*"匹配能够失去src="test.jpg" width="60px" height="80px"
匹配时会始终检索到最初一个引号再进行

表达式src=".*?"能够失去后果:src="test.jpg"
匹配到第一个"就完结了一次匹配。不会持续向后匹配。

援用——应用后面括号内的内容

环视

o.o 看不太懂

参考

https://taoshu.in/hello-regex...