[Skill]从零掌握正则表达式

2020-06-13  本文已影响0人  TOMOCAT

前言

无论你是出于什么原因需要掌握正则表达式(诸如爬虫、文本检索、后端服务开发或Linux脚本),如果之前从没接触过正则表达式(比如我)很容易在如山般的公式中迷失,以至于你在项目写的正则表达式很可能会因为组织混乱而被后来的开发者吐槽。

正则表达式Regular Expression本质上是一种文本模式,包括普通字符和特殊字符(也被称为元字符),使用一个字符串表达式来匹配符合该规则的字符串。

学习工具:正则表达式可视化工具

https://jex.im/regulex/#!flags=&re=%5E(a%7Cb)*%3F%24

这个网站可以可以用可视化的方式展示正则表达式的匹配模式,比如^[0-9]+abc$表示从字符串的开头开始匹配一或多个数字,然后以abc结尾。

image.png

https://regexr.com/

这个网站可以用于测试你写的正则表达式匹配效果,比如Re(\w)+表示匹配以Re开头的字符串。

image.png

从通配符讲到正则表达式

在操作系统上或者SQL中我们经常接触到通配符的使用,比如模糊搜索文件(比如*.dat表示匹配所有以.dat为后缀的文件)。常用的通配符包括:

上面这两个通配符尽管用途很广,但很难穷尽任意字符串匹配的场景,正则表达式的功能更加强大,足以覆盖字符串匹配的大部分场景。上面网站展示的两个例子已经说明其的强大之处,接下来我们只需要掌握它的语法即可。

正则表达式最常用的几个用途包括:

正则表达式语法

普通字符包括没有被显式指定为元字符的所有可打印和非打印字符,包括所有的大写和小写字母、数字、标点符号和一些其他符号。

1. 非打印字符

非打印字符也可以是正则表达式的组成部分。

2. 特殊字符

如果要匹配这些特殊字符的话,可以在其前面加上一个反斜杠进行转义。

3. 限定符

限定符用于指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。

注意*+限定符都是贪婪的,因为它们会尽可能多的匹配文案,只要在它们的后面加上一个?就可以实现非贪婪或者最小匹配。

4. 定位符

5. 选择

用圆括号将所有选择项括起来,相邻的选择项之间用|发那个,但用圆括号会有一个副作用使得相关的匹配都被缓存,此时可用?:放在第一个选项前来消除这种副作用。

6. 反向引用

对一个正则表达式模式或者部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从1开始,最多可以存储99个捕获的字表达式,每个缓冲区都可以用\n访问。

可以使用非捕获元字符?:?=?!来重写捕获。

反向引用有两个主要的用途:

相当于查询重复出现两次的单词,下面的python代码举了一个例子:

import re

"""
re.search(pattern, string, flags=0)
pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位, 用于控制正则表达式的匹配方式, 包括是否区分大小写和多行匹配等
"""

# 查询重复出现两次的单词
target_str = "Is is the cost of of gasoline going up up"
match_str = re.findall(r'\b([a-z]+) \1\b', target_str, re.M|re.I)

print("match str : ", match_str)

==================================================================
# 输出结果
# match str :  ['of', 'up']

比如我们可以将url解析成域名、端口等元素:

import re

"""
re.search(pattern, string, flags=0)
pattern: 匹配的正则表达式
string: 要匹配的字符串
flags: 标志位, 用于控制正则表达式的匹配方式, 包括是否区分大小写和多行匹配等
返回值: 是一个list, 表示所有匹配到的子字符串
"""

target_str = "http://www.runoob.com:80/html/html-tutorial.html"
match_str = re.findall(r'(\w+):\/\/([^/:]+)(:\d*)?([^# ]*)', target_str, re.M|re.I)

print("match str : ", match_str[0])

==================================================================
# 第一个括号子表达式包含 http
# 第二个括号子表达式包含 www.runoob.com
# 第三个括号子表达式包含 :80
# 第四个括号子表达式包含 /html/html-tutorial.html
# 输出结果
# match str :  ('http', 'www.runoob.com', ':80', '/html/html-tutorial.html')

7. 元字符

运算符优先级

运算符优先级从高到低如下:

Reference

[1] https://www.runoob.com/regexp/regexp-tutorial.html

上一篇下一篇

猜你喜欢

热点阅读