微信公众号:码农充电站pro

个人主页:https://codeshellme.github.io


0,什么是正则表达式

正则表达式Regular Expression简写为Regex),又称为规则表达式,它是一种强大的文本匹配模式,其用于在字符串中查找匹配符合特定规则的子串。

正则表达式是独立于编程语言而存在的,它并不依赖于某种编程语言。只要一种编程语言实现了正则表达式引擎,那么这种编程语言,就具备了正则表达式模式匹配的功能。每种工具编程语言对正则表达式的实现,虽有细节上的不同,但基本的使用是相同的。

正则表达式的基本工作原理如下:

1,正则表达式的由来

1956 年,美国数学家Stephen Kleene 在两位神经生理学家(Warren McCullochWalter Pitts)的早期工作的基础上,发表了一篇标题为神经网事件的表示法的论文,由此引入了正则表达式的概念。

之后,Unix 之父Ken Thompson把这一成果应用于计算搜索算法的一些早期研究。随后,他将这一符号系统应用于Unix 系统中的 qed 编辑器,这是正则表达式的第一个实用程序。

此后,正则表达式被广泛的应用于类Unix 系统的工具中,如 grepperl 等。

2,正则表达式工具

RegexBuddy 是一个很不错的软件。

Regexr 是一个在线工具。

3,正则表达式语法

正则表达式由一些普通字符(比如英文字母,数字)和元字符(代表特定含义)组成。

正则表达式作为一个字符模板,在字符串中匹配一个或多个符合特定规则的子串。

3.1,元字符

元字符就是包含特定含义的字符。如果想匹配这些元字符,需要使用转义字符\ 进行转义。

下表是一些常用的元字符:

字符 含义
\ 转义字符,常用于转义元字符
. 匹配除换行符\n 之外的任何单字符
$ 匹配字符串的结尾位置
^ 匹配字符串的开始位置。当写在中括号[]内时,表示不匹配该中括号中的字符集合
[^xy] 匹配非x非y字符
() 被小括号包含的多个字符,将作为一整个字符
(pattern) 写在小括号()内的表达式,表示一个分组,用于提取内容
(?:pattern) 只表示一个分组,不提取内容
[] 被中括号包含的多个字符,这多个字符的关系是逻辑或的关系
[xyz] 字符集合,匹配xyz
[0-9] 匹配09之间的数字
[a-z] 匹配az之间的字符
[^a-z] 匹配不在az范围内的任意字符
| 写在两个字符之间,代表逻辑或的关系
x|y 匹配xy
\b 匹配一个单词边界
\B 匹配非单词边界
\d 匹配一个数字字符,等价于[0-9]
\D 匹配一个非数字字符,等价于[^0-9]
\s 匹配任何空白字符,包括空格制表符
\S 匹配任何非空白字符
\w 匹配字母数字下划线,等价于[A-Za-z0-9_]
\W 匹配非字母非数字非下划线,等价于[^A-Za-z0-9_]
\f 匹配换页符
\n 匹配换行符
\r 匹配回车符
\t 匹配制表符
\v 匹配垂直制表符

3.2,限定符

限定符也属于元字符,用来限定一个子表达式出现的次数。

字符 含义
* 匹配前面的子表达式零次多次
+ 匹配前面的子表达式一次多次
? 匹配前面的子表达式零次一次
{n} 匹配前面的子表达式n次
{n,} 匹配前面的子表达式至少n次
{n,m} 匹配前面的子表达式n 到m 次

4,正则表达式示例

我们逐个介绍一下每种元字符的使用方式,下面的例子我们都使用RegexBuddy 软件来演示。

4.1,转义字符\

转义字符用来对一些元字符进行转义,使这些元字符失去其特定的含义,只表示一个普通的字符。

比如我们想匹配字符串aaa^bbb 中的a^b 子串,我们需要用模式a\^b 来匹配,^ 之前需要加一个转义字符\



4.2,元字符.

元字符. 可匹配任意(除了换行符\n)的单字符,意思就是. 可以代表任意(除了换行符\n)的单字符。



4.3,开始位置^与结束位置$

符号^ 表示匹配的子串在行首,符号$ 表示匹配的子串在行尾


匹配行首


匹配行尾


行首行尾

4.4,逻辑或|

符号| 写在两个子表达式之间表示逻辑或的意思。

例如模式串ab|cd,匹配abcd



4.5,限定符

限定符用于限定一个子表达式出现的次数,一共6 种,这里给出一些示例。

符号*

模式串ab*c,表示字符ac 之间需要出现0 次多次字符b



符号+

模式串ab+c,表示字符ac 之间需要出现1 次多次字符b,即至少出现1次字符b



符号?

模式串ab?c,表示字符ac 之间需要出现0 次1次字符b



符号{n}{n,}{n,m}

  • ab{3}c:符号b 出现的次数必须是3
  • ab{3,}c:符号b 出现的次数必须大于等于3
  • ab{3,5}c:符号b 出现的次数必须在35 之间,包括35


4.6,字符簇[]

写在中括号[] 内的多个字符代表逻辑或的意思。

模式串a[bef]c,表示ac中间的字符必须是bef



当符号^ 写在中括号[] 内时,表示逻辑非的意思。

模式串a[^bef]c,表示ac中间的字符不能是bef



符号- 写在中括号[],表示范围的意思:

示例 含义
[a-z] 表示az 之间的任意字符
[A-Z] 表示AZ 之间的任意字符
[0-9] 表示09 之间的任意数字,含义同\d
[^0-9] 表示任意非数字,含义同\D
[A-Za-z0-9_] 表示任意字母数字下划线 ,含义同\w
[^A-Za-z0-9_] 表示任意非字母非数字非下划线 ,含义同\W
[ \f\r\t\n] 表示任意的空白字符,含义同\s
[^ \f\r\t\n] 表示任意的非空白字符,含义同\S

4.7,字符组合()

写在小括号()中的多个字符,会被看成一个整体。



4.8,单词边界\b\B

符号\b 是指一个单词边界,比如空白字符和标点符号等。

符号\B 表示非单词边界



5,贪婪与非贪婪模式

正则表达式中贪婪的意思就是贪多,意思就是正则在匹配的过程中,总是去匹配尽可能多的字符,符号? 可以将贪婪转换为非贪婪



6,在Python 中使用正则

Python 中提供了re 模块,用于支持正则表达式功能。

python 中一般在表达式前加r,表示原始字符,不用考虑转义的问题。例如r'abc'

下面打开python 终端:

  • 首先引入模块,import re
  • help(re) 可查看re 模块帮助手册
  • dir(re) 可查看其支持的属性和方法
>>> python		`打开python 终端`
_____________________________________________
Python 2.7.17 (default, Nov 7 2019, 10:07:09)
[GCC 7.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information. >>> import re # 引入re 模块
>>>
>>> help(re) # 查看帮助手册
>>>
>>> dir(re) # 查看re 支持的属性和方法

6.1,re 模块常用方法

方法 含义
match 用于匹配表达式
search 查找匹配项
findall 查找所有的匹配项
compile 编译正则表达式

详细解释:

match(pattern, string, flags=0)
Try to apply the pattern at the start of the string, returning
a match object, or None if no match was found. search(pattern, string, flags=0)
Scan through string looking for a match to the pattern, returning
a match object, or None if no match was found. findall(pattern, string, flags=0)
Return a list of all non-overlapping matches in the string. If one or more groups are present in the pattern, return a
list of groups; this will be a list of tuples if the pattern
has more than one group. Empty matches are included in the result. compile(pattern, flags=0)
Compile a regular expression pattern, returning a pattern object.

可以看到,每个方法中都有一个flag 参数,它表示匹配模式,默认值为0,表示普通模式。

flag 参数的值有以下几种选择,可以使用符号| 连接多种选择:

`I/IGNORECASE`  Perform case-insensitive matching.
`L/LOCALE` Make \w, \W, \b, \B, dependent on the current locale.
`M/MULTILINE` "^" matches the beginning of lines (after a newline)
as well as the string.
"$" matches the end of lines (before a newline) as well
as the end of the string.
`S/DOTALL` "." matches any character at all, including the newline.
`X/VERBOSE` Ignore whitespace and comments for nicer looking RE's.
`U/UNICODE` Make \w, \W, \b, \B, dependent on the Unicode locale.

6.2,match 方法

re.match 尝试从字符串的起始位置开始匹配:

  • 成功:返回SRE_Match 对象
  • 失败:返回None
>>> m = re.match(r'abc', 'abcde')
>>> print m # 匹配成功
<_sre.SRE_Match object at 0x7f91544cff80>
>>>
>>>
>>> m = re.match(r'abc', 'fabcde')
>>> print m # `fabcde` 不是以`abc` 开头,匹配失败
None
>>>

6.3,search 方法

re.search 扫描整个字符串,直到找到第一个成功的匹配:

  • 成功:返回SRE_Match 对象
  • 失败:返回None
>>> m = re.search(r'abc', 'abcde')
>>> print m # 匹配成功
<_sre.SRE_Match object at 0x7f91544cff80>
>>>
>>> m = re.search(r'abc', 'fabcde')
>>> print m # 匹配成功
<_sre.SRE_Match object at 0x7f9154521b90>

6.4,findall 方法

re.findall 在字符串中查找所有匹配的子串:

  • 成功:返回一个列表
  • 失败:返回空列表[]
>>> re.findall(r'abc', 'fabcdeabc')
['abc', 'abc'] # 找到两个`abc` 子串
>>>
>>> re.findall(r'abce', 'fabcdeabc')
[] # 没找到子串
>>>

6.5,compile 方法

在使用正则时,re 模块会先将正则表达式进行编译,然后才会去字符串中匹配。

如果一个正则表达式会使用很多次,我们可以使用re.compile 方法对表达式进行预编译,这样就不会在每次用到这个表达式时都进行编译,有助于提高效率。

该方法返回一个SRE_Pattern 对象,该对象又包含matchsearchfindall 等方法,使用方法如下:

>>> reg =  re.compile(r'abc')      # 编译
>>>
>>> type(reg)
<type '_sre.SRE_Pattern'>
>>>
>>> reg.findall('fabcdeabc') # 找到两个
['abc', 'abc']
>>>
>>> reg.match('fabcdeabc') # 没有匹配上
>>>
>>> reg.search('fabcdeabc') # 匹配上
<_sre.SRE_Match object at 0x7f9154521b90>

6.6,SRE_Match 对象

SRE_Match 对象用于获取分组,写在小括号()内的表达式是一个分组。

>>> # 正则中包含两个分组
>>> m = re.match(r'(\d*)-(\w*)', '123-abc-')
>>> m
<_sre.SRE_Match object at 0x7f91544e0ae0>
>>> m.group(0) # 获取整个匹配的串,同 m.group()
'123-abc'
>>> m.group(1) # 获取第一个分组
'123'
>>> m.group(2) # 获取第二个分组
'abc'
>>>

6.7,match,search,findall 比较

我们来看下matchsearchfindall 三个方法的异同点:

  • match:必须从字符串的开头匹配,只会有一个匹配项,返回结果是SRE_Match 对象
  • search:扫描整个字符串,直到匹配到第一个为止,只会有一个匹配项,返回结果是SRE_Match 对象
  • findall:扫描整个字符串,返回所有的匹配项,返回结果是一个字符串列表

(完。)


欢迎关注作者公众号,获取更过技术干货。

Regex 正则表达式入门的更多相关文章

  1. Python 正则表达式入门(初级篇)

    Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门所写. 转载请写明出处 引子 首先说 正则表达式是什么? 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达 ...

  2. 转载 Python 正则表达式入门(初级篇)

    Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门所写.转载请写明出处 引子 首先说 正则表达式是什么? 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达式 ...

  3. 正则表达式入门之学习路线&七个问题

    由于工作需求,需要使用正则表达式查找满足某种模式的字符串,但因为之前都没有接触过相关内容,最开始的时候看了一些已经被别人写好了的正则表达式,本来打算可能可以直接使用: 最全的常用正则表达式大全——包括 ...

  4. python正则表达式入门篇

    文章来源于:https://www.cnblogs.com/chuxiuhong/p/5885073.html Python 正则表达式入门(初级篇) 本文主要为没有使用正则表达式经验的新手入门所写. ...

  5. Java正则表达式入门基础篇

    正则表达式是一种可以用于模式匹配和替换的规范,一个正则表达式就是由普通的字符(例如字符a到z)以及特殊字符(元字符)组成的文字模式,它 用以描述在查找文字主体时待匹配的一个或多个字符串.正则表达式作为 ...

  6. Python 正则表达式入门(中级篇)

    Python 正则表达式入门(中级篇) 初级篇链接:http://www.cnblogs.com/chuxiuhong/p/5885073.html 上一篇我们说在这一篇里,我们会介绍子表达式,向前向 ...

  7. 分享录制的正则表达式入门、高阶以及使用 .NET 实现网络爬虫视频教程

    我发布的「正则表达式入门以及高阶教程」,欢迎学习. 课程简介 正则表达式是软件开发必须掌握的一门语言,掌握后才能很好地理解到它的威力: 课程采用概念和实验操作 4/6 分隔,帮助大家理解概念后再使用大 ...

  8. JavaScript正则表达式详解(一)正则表达式入门

    JavaScript正则表达式是很多JavaScript开发人员比较头疼的事情,也很多人不愿意学习,只是必要的时候上网查一下就可以啦~本文中详细的把JavaScript正则表达式的用法进行了列表,希望 ...

  9. 转:C++ Boost/tr1 Regex(正则表达式)快速指南

    C++ Boost/tr1 Regex(正则表达式)快速指南 正则表达式自Boost 1.18推出,目前已经成为C++11(tr1)的标准部分. 本文以Boost 1.39正则表达式为基础,应该广泛适 ...

随机推荐

  1. 【python】利用jieba中文分词进行词频统计

    以下代码对鲁迅的<祝福>进行了词频统计: import io import jieba txt = io.open("zhufu.txt", "r" ...

  2. 如何在云开发静态托管中使用Hugo

    如何在云开发静态托管中使用Hugo 介绍 hugo是一个用Go编写的静态站点生成器,由于具有丰富的主题资源和有比较丰富的主题资源和较好的生成速度. 云开发(CloudBase)是一款云端一体化的产品方 ...

  3. ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 以及 同步的集合类 Hashtable 和 Vector Collections.synchronizedMap 和 Collections.synchronizedList 区别缺点

    ConcurrentHashMap和 CopyOnWriteArrayList提供线程安全性和可伸缩性 DougLea的 util.concurrent 包除了包含许多其他有用的并发构造块之外,还包含 ...

  4. Redis linux 下安装

    Redis linux 下安装 下载Redis安装包,可以从Redis中文网站中下载 下载地址:http://www.redis.cn/download.html Redis4.0 稳定版本 使用&l ...

  5. Linux 命令系列之 seq

    简介 seq -- print sequences of numbers seq 命令可以输出各种有规律的数字. 用法 usage: seq [-w] [-f format] [-s string] ...

  6. d3限制范围缩放和平移升级到版本4

    感谢您提供帮助以更新下面的代码以在版本4中工作.我已将zoom.behaviour更改为d3.zoom,但我不清楚所需的其他更改.看起来比v3还要复杂! <!DOCTYPE html> & ...

  7. Daily Scrum 12/29/2015

    Process: Zhaoyang: Add the Time bar feature in the APP and complete the Speech API. Yandong: Do some ...

  8. Matlab学习-(4)

    1. 函数 1.1 原始方法 之前我调用函数的方法是,首先写好函数文件,然后保存,然后在主函数中调用.这种方法的不足在于会导致你的工作目录的文件太多,从而导致很乱.在网上找了一些解决方法. 1.2 本 ...

  9. IN612 IN612L蓝牙5.0 SoC芯片替换NRF52832/NRF52840

    IN612L是美国公司INPLAY的SOC产品系列之一,具有多模协同2.4G无线协议栈,支持2.4G私有协议栈以及蓝牙5.0全协议栈的SOC芯片.如2mbps高数据速率模式,125kbps/500kb ...

  10. PHP 语法字符串函数 strcmp、strlen 使用及实现

    说明 这里基于 php7.2.5 进行测试,php7 之后内部结构变化应该不是太大,但与 php5.X 有差别. 函数分类 用户自定义函数 say(); function say() { echo & ...