杂物 | 正则表达式

144 阅读2分钟

正则表达式

基础

多种匹配模式

实例描述
[Pp]ython匹配 “Python” 或 “python”。
rub[ye]匹配 “ruby” 或 “rube”。
[abcdef]匹配中括号内的任意一个字母。
[0-9]匹配任何数字。类似于 [0123456789]。
[a-z]匹配任何小写字母。
[A-Z]匹配任何大写字母。
[a-zA-Z0-9]匹配任何字母及数字。
[^au]除了au字母以外的所有字符。
[^0-9]匹配除了数字外的字符。
实例描述
.匹配除\n之外的任何单个字符。要匹配包括\n在内的任何字符,请使用像(.|\n)的模式。
rub[ye]字符集合。匹配所包含的任意一个字符。例如,[abc]可以匹配plain中的a
?匹配一个字符零次或一次,另一个作用是非贪婪模式
+匹配1次或多次
*匹配0次或多次
\b匹配一个单词边界,也就是指单词和空格间的位置。
例如,er\b可以匹配never中的er,但不能匹配verb中的er
\B匹配非单词边界。
er\B能匹配verb中的er,但不能匹配never中的er
\d匹配任何字母及数字。
\D匹配一个非数字字符。等价于 [^0-9]。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w匹配包括下划线的任何单词字符。等价于[A-Za-z0-9_]
\W匹配任何非单词字符。等价于 [^A-Za-z0-9_]
\n匹配一个换行符。等价于\x0a和\cJ。
\r匹配一个回车符。等价于\x0d和\cM。

进阶

分组

  • 用法:使用()即可。

63ad7ed7502cc6f46263127dc93fe157.png

Group 1Group 2
11451419198
  • 使用分组提取数据
    • 文本:<div>hi</div>
    • 这种情况未使用分组,默认全匹配
      • 正则:<div>.*?</div>
      • 结果:<div>hi</div>
    • 使用分组就可以将对应的数据提取出来
      • 正则:<div>(.*?)</div>
      • 结果:$1hi

或者

比如需要查找某几个特定格式的文件的时候就可以使用这个

  • 用法:
    • 分组的同时还可以使用 或者(or)条件,使用|符号即可。

      • 正则:\.(mp4|mp3)

      851e8d66ce7c3c8ce30a635251bdd116.png


Group 1Group 2
.mp4.mp3

非捕获分组(忽略分组)

如果此时想要的数据为除某个分组以外的其他分组的数据,那么就可以使用非捕获分组

  • 用法:(?:表达式)

    比如,此时想要匹配下列文本中一个美元符号$中的数据(美元符号$,左右不能有其他的美元符号$

    $1145141919810$
    $wocbushiba$
    $zenmenibufuqima$
    114514$1919810$$
    $$ suoding $$
    $$$ ???????? $$$$
    
    • 正则:(?:\$)([^\$].*[^\$])(?:\$)(\n)

      6da0a9978eba4fbebb2b9b02f377a3e5.png

      d0236a24d6e2df7d40de9c304ef5ad8c.png

      Group 1Group 2
      1145141919810均为换行符
      wocbushiba
      zemenibufuqima

回溯引用

如果想要匹配html标签中的内容就可以使用回溯引用

比如,使用这个正则表达式匹配html中的内容:

  • 正则:<\w+>.*?</\w+>
  • 文本:
    <span>蒸馍?你不扶器吗?</span>
    <span>蒸馍?你不扶器吗?2</p>
    

9d55bbe3529ef778ffc60c220ebd696f.png

可以看到,并不能正确匹配对应的一对标签,结果不正确,所以要解决这个问题就可以使用回溯引用

  • 用法:\N,意思为引用为编号为N的Group(分组)。

    所以上面的正则表达式就可以改为:<(\w+)>.*?</\1>

df6d5f8a4d3125b1ad8cf5bb774ff5c3.png

0a04021e2e77b8a377abfdbbac616c93.png

Group 1Group 2
span蒸馍?你不扶器吗?

断言(预搜索|环视)

断言也称为环视或者预搜索,分别有4种类型:

  1. 正向先行断言
  2. 反向先行断言
  3. 正向后行断言
  4. 反向后行断言

先行断言

简单理解就是一个字符串,从左往右边看,根据能否满足对应的正则表达式的条件来匹配对应的内容。

  • 正向先行断言

    • 用法:(?=表达式),指在某个位置向右看,表示所在位置右侧必须能匹配表达式

    • 比如想要提取test关键字,要求test后面必须带need关键字,就可以写为:test(?=need)

      6b32057285dce4b7afcc476db61ad5b7.png

    • 衍生的用法:验证密码强度

      • 至少一个大写字母
      • 至少一个小写字母
      • 至少一个数字
      • 至少8个字符

      正则:(?=.*?[a-z])(?=.*?[A-Z])(?=.*?[\d]).{8,}

      be28e0f9d1118ff506fff7c0191fe522.png

      3dd0ab0d40bf308bf59e2acfa9960f46.png

  • 反向先行断言

    • 用法:(?!表达式),指在某个位置向右看,表示所在位置右侧必须**不能**匹配表达式

    • 比如想要提取test关键字,要求test后面**不能**带need关键字,就可以写为:test(?!need)

      6b32057285dce4b7afcc476db61ad5b7.png

    • 应用:不匹配某个类型的标签,比如a标签

      • 正则:<((?!a)\w+)>(.*)</\1>

      2be9c5bb19bbcf7b951e3e4747580c70.png

      cd5e71a47b09daef2b98c1602edfb0a2.png


Group 1Group 2
div111
h1
h4
pcode

后行断言

先行断言从左往右看,后行断言从右往左看

  • 正向后行断言
    • 用法:(?<=表达式),指在某个位置向左看,表示所在位置左侧必须能匹配表达式

    • 例如:如果要取出喜欢两个字,要求喜欢的前面有我,后面有你,这个时候就要这么写:(?<=我)喜欢(?=你)。

      4f7d9dea5b04cbf5694f67319d3db9f3.png

  • 反向后行断言
    • 用法:(?<!表达式),指在某个位置向左看,表示所在位置左侧不能匹配表达式

    • 例如:如果要取出喜欢两个字,要求喜欢的前面没有我,后面没有你,这个时候就要这么写:(?<!我)喜欢(?!你)。

      1e750b005da1746ced7af0000fd645f2.png

    • 应用:使用正则表达式匹配所有两个$符号中的数据

      f92c878de3b4a30105cf980aded2e200.png

推荐的练习网站

参考