[Skill]从零掌握正则表达式
前言
无论你是出于什么原因需要掌握正则表达式(诸如爬虫、文本检索、后端服务开发或Linux
脚本),如果之前从没接触过正则表达式(比如我)很容易在如山般的公式中迷失,以至于你在项目写的正则表达式很可能会因为组织混乱而被后来的开发者吐槽。
正则表达式Regular Expression
本质上是一种文本模式,包括普通字符和特殊字符(也被称为元字符),使用一个字符串表达式来匹配符合该规则的字符串。
学习工具:正则表达式可视化工具
这个网站可以可以用可视化的方式展示正则表达式的匹配模式,比如^[0-9]+abc$
表示从字符串的开头开始匹配一或多个数字,然后以abc
结尾。
这个网站可以用于测试你写的正则表达式匹配效果,比如Re(\w)+
表示匹配以Re
开头的字符串。
从通配符讲到正则表达式
在操作系统上或者SQL
中我们经常接触到通配符的使用,比如模糊搜索文件(比如*.dat
表示匹配所有以.dat
为后缀的文件)。常用的通配符包括:
?
:匹配0
或者1
个任意字符*
:匹配0
或者多个任意字符
上面这两个通配符尽管用途很广,但很难穷尽任意字符串匹配的场景,正则表达式的功能更加强大,足以覆盖字符串匹配的大部分场景。上面网站展示的两个例子已经说明其的强大之处,接下来我们只需要掌握它的语法即可。
正则表达式最常用的几个用途包括:
- 字符串模式校验:比如我们后端的
http
服务受到参数时校验该字符串是否是日期、电话和身份证等 - 文本批量替换:可以对满足匹配的规则的文本进行全部替换
- 从字符串中提取子字符串:比如在爬虫的时候从整个
html
页面中提取需要的子字符串 - 检查一个字符串中是否包含某个类型的字符串
正则表达式语法
普通字符包括没有被显式指定为元字符的所有可打印和非打印字符,包括所有的大写和小写字母、数字、标点符号和一些其他符号。
1. 非打印字符
非打印字符也可以是正则表达式的组成部分。
\cx
:匹配由x
指明的控制字符,例如\cM
匹配一个Control-M
或者回车符,x
的值必须为A-Z
或a-z
之一\f
:匹配一个换页符\n
:匹配一个换行符\r
:匹配一个回车符\s
:匹配任何空白字符,包括空格、制表符和换页符等,等价于[\f\n\r\t\v]
\S
:匹配任何非空白字符,等价于[^\f\n\r\t\v]
\t
:匹配一个制表符\v
:匹配一个垂直制表符
2. 特殊字符
如果要匹配这些特殊字符的话,可以在其前面加上一个反斜杠进行转义。
\$
:匹配输入字符串的结尾位置,如果设置了RegExp
的Multiline
属性则$
也匹配\n
或\r
()
:标记一个子表达式的开始和结束位置,子表达式可以获取供以后使用*
:匹配前面的子表达式零次或多次+
:匹配前面的子表达式一次或多次.
:匹配除换行符\n
外的任意单个字符[
:标记一个中括号表达式的开始?
:匹配前面的子表达式零次或一次,或指明一个非贪婪限定符\
:将下一个字符标记为或特殊字符、或原义字、或向后引用、或八进制转义符^
:匹配输入字符串的开始位置,如果实在方括号表达式中使用表示不接受该方括号表达式中的字符集合{
:标记限定符表达式的开始|
:指明两项之间的一个选择
3. 限定符
限定符用于指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。
*
:匹配前面的子表达式零次或多次+
:匹配前面的子表达式一次或多次?
:匹配前面的子表达式零次或一次{n}
:匹配确定的n
次{n,}
:至少匹配n
次{n,m}
:最少匹配n
次最多匹配m
次
注意
*
和+
限定符都是贪婪的,因为它们会尽可能多的匹配文案,只要在它们的后面加上一个?
就可以实现非贪婪或者最小匹配。
4. 定位符
^
:匹配输入字符串开始的位置$
:匹配输入字符串结尾的位置\b
:匹配一个单词边界,即字与空格间的位置\B
:非单词办结匹配
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. 元字符
\
:将下一个字符标记为特殊字符,或原义字符,或向后引用,或一个八进制转义符^
:匹配输入字符串的开始位置$
:匹配输入字符串的结束为止*
:匹配前面的子表达式零次或多次+
:匹配前面的子表达式一次或多次?
:匹配前面的子表达式零次或一次{n}
:匹配确定的n
次{n,}
:匹配至少n
次{n,m}
:匹配至少n
次,至多m
次?
:当该字符紧跟在任何一个其他限制符后面时表示匹配模式是非贪婪的.
:匹配除换行符\n \r
外的任何单个字符(pattern)
:匹配pattern
并捕获这一结果(?:pattern)
:匹配pattern
并不捕获这一结果(?=pattern)
:正向肯定预查,在任何匹配pattern
的字符串开始处匹配查找字符串,这是一个非捕获匹配,即该匹配不需要获取供以后使用(?!pattern)
:正向否定预查,在任何不匹配该pattern
的字符串开始处匹配字符串,这是一个非获取匹配,即该匹配不需要获取供以后使用(?<=pattern)
:反向肯定预查,与正向肯定预查类似,只是方向相反(?<!pattern)
:反向否定预查,与正向否定预查类似,只是方向相反x|y
:匹配x
或y
[xyz]
:匹配所包含的任意一个字符[^xyz]
:匹配未包含的任意字符[a-z]
:匹配指定范围内的任意字符[^a-z]
:匹配任何不在指定范围内的任意字符\b
:匹配一个单词边界,即单词和空格间的位置\B
:匹配非单词边界\cx
:匹配由x
指明的控制字符\d
:匹配一个数字字符\D
:匹配一个非数字字符\f
:匹配一个换页符\n
:匹配一个换行符\r
:匹配一个回车符\s
:匹配任何空白字符,等价于[\f\n\r\t\v]
\S
:匹配任何非空白字符\t
:匹配一个制表符\v
:匹配一个垂直制表符\w
:匹配字符、数字、下划线,等价于[A-Za-z0-9]
\W
:匹配非字符、数字、下划线\xn
:匹配n
,其中n
为十六进制转义值\n
:标记一个八进制转义值或向后引用
运算符优先级
运算符优先级从高到低如下:
\
:转义符(),(?:),(?=),[]
:圆括号和方括号*, +, ?, {n}, {n,}, {n,m}
:限定符^, $, \任何元字符、任何字符
:定位点和序列(即位置和顺序)|
:“或”操作
Reference
[1] https://www.runoob.com/regexp/regexp-tutorial.html
[Skill]从零掌握正则表达式的更多相关文章
- [Skill]从零掌握80%的业务查询SQL语句
前言 本篇文章的主要目的是帮助初学者快速入门SQL查询,从而解决实际业务中80%的SQL查询问题. 本文主要框架如下: 上篇:介绍SQL的语法顺序和执行顺序 中篇:介绍条件子句.分组查询和排序的细节 ...
- [Skill]VBA零基础入门及实践:根据链接展示图片
简介 VBA(Visual Basic for Applications)是依附在应用程序(例如Excel)中的VB语言.只要你安装了Office Excel就自动默认安装了VBA,同样Word和Po ...
- 正则表达式 自学笔记整理记录 EASY REGEX~
整理正则表达式篇 -wuian7yulian 基础知识介绍 : 1> 字符串的组成: 对于字符串"ABC"来说,其包 ...
- [No0000100]正则表达式匹配解析过程分析(正则表达式匹配原理)&regexbuddy使用&正则优化
常见正则表达式引擎引擎决定了正则表达式匹配方法及内部搜索过程,了解它至关重要的.目前主要流行引擎有:DFA,NFA两种引擎. 引擎 区别点 DFA Deterministic finite autom ...
- 正则表达式(Regular Expression, RegEx)学习入门
1. 概述 正则表达式(Regular Expression, RegEx)是一种匹配模式,描述的是一串文本的特征. 正如自然语言中高大.坚固等词语抽象出来描述事物特征一样,正则表达式就是字符的高度抽 ...
- 正则表达式: NFA引擎匹配原理
NFA引擎匹配原理 1 为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动 ...
- NFA引擎匹配原理
1 为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动听的乐曲,但他/她或 ...
- Java 笔试面试 算法编程篇 一
方法 1 /* ********************************************************************************** 1.编写一个程序, ...
- python 正则表达式之零宽断言
零宽断言:用于查找特定内容之前或之后的内容,但并不包括特定内容本身.对于零宽断言来说,我认为最重要的一个概念是位置,零宽断言用于指定一个位置,这个位置应该满足一定的条件(它附近满足什么表达式),并且这 ...
随机推荐
- [转]自动驾驶平台Apollo 2.5环境搭建
原文地址:https://blog.csdn.net/jinzhuojun/article/details/80210180,转载主要方便随时查阅,如有版权要求,请及时联系. 我们知道,自动驾驶在学界 ...
- 字节码增强技术-Byte Buddy
本文转载自字节码增强技术-Byte Buddy 为什么需要在运行时生成代码? Java 是一个强类型语言系统,要求变量和对象都有一个确定的类型,不兼容类型赋值都会造成转换异常,通常情况下这种错误都会被 ...
- E百科 | 基于MEC的边缘AI服务
简介: 阿里云边缘计算团队付哲解读5G下热门场景:边缘AI.作者:阿里云付哲,计算机科学与技术专业博士后,在流量检测.资源调度领域有深入研究,其论文<Astraea: Deploy AI Ser ...
- 【重磅】iNeuOS工业互联平台,系统集成业务模型和WEB组态视图建模集成3D模型
目 录 1. 概述... 1 2. 平台演示... 2 3. 系统集成业务模型... 2 4. WEB组态视图建模集成3D模型... 3 5. ...
- 身份认证:JSON Web Token
JSON Web Token(JWT)是一种基于JSON的开放标准((RFC 7519),也是目前最流行的跨域认证解决方案. 传统的 cookie 认证方式看起来遵守了 REST 架构的无状态要求,但 ...
- 封装fetch请求失败和超时再次请求
转: 封装fetch请求失败和超时再次请求 function _fetch(fetch_promise, timeout) { var abort_fn = null; //这是一个可以被reject ...
- 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
剑指 Offer 21. 调整数组顺序使奇数位于偶数前面 Offer 21 这题的解法其实是考察快慢指针和头尾指针. package com.walegarrett.offer; /** * @Aut ...
- HDOJ-1301(最小生成树模板+Prim算法)
Jungle Roads HDOJ-1301 这是最小生成树的水题,唯一要注意的就是那个n,其实输入只有n-1行. #include<iostream> #include<cstdi ...
- strick-footer 粘边布局
当网页缩小, 缩放到一定高度时(这个高度就是页面内容高度)footer的页尾自动消失,这个就叫做粘边布局 strick-footer 粘边布局基本思路: 主体{ height:100%; } 内容体{ ...
- python基础学习之函数基础和部分内置函数
在函数调用的时候,必备参数必须要传入 函数定义: def 函数名: 代码块pass return 返回值 函数名命名规则: 字母.数字和下划线组成,和变量命名规则一致 pass在这里表示什么都没有 ...