上一篇博客《python之正则表达式1》学习了正则表达是的10种syntax。

本片文章分享7种正则语法,理解起来会比前一篇文章中的语法难度大一点,但是我相信,如果你认真的阅读本文,一定有所收获!!!

文章目录

  • 正则表达式的语法
    • \
    • \[\](character class)
    • |(alternation)
    • (...)
    • (?:...)
    • (?P\

正则表达式的语法

\

Either escapes special characters (permitting you to match characters like '*', '?', and so forth), or signals a special sequence;

反斜杠(backslash) 有两种作用:1. 特殊字符转义;2. 表示特定的序列(将在后面的介绍);

在python字符串中,反斜杠(\)有转义的作用,可以将某些特殊字符的特殊作用"去掉",仅表示字符本身。例如,仅仅是想匹配字符串中的星号字符本身,那么就要使用\将星号转义。通常为了使编码更简洁,pattern 使用 raw string来表示。

import re
test_str1 = '6=2*3'
RE_BACKSLASH = r'\*'
print(re.search(RE_BACKSLASH, test_str1))   # <re.Match object; span=(3, 4), match='*'>

[](character class)

Characters can be listed individually, e.g. [amk] will match 'a', 'm', or 'k'.

[]字符集 用来告诉正则引擎 只匹配[]中的多个字符中的某一个字符。只需要将待匹配的字符放入中括号即可。

例如,有些单词在美式英语和英式英语中,会有个别的字母不一样,要想兼容两种情况,有时候character class就非常有用。

import re
test_str1 = 'charactor'
test_str2 = 'character'
RE_SQUARE_BRACKET = r'charact[oe]r'
print(re.search(RE_SQUARE_BRACKET, test_str1))  # 输出结果为 <re.Match object; span=(0, 9), match='charactor'>
print(re.search(RE_SQUARE_BRACKET, test_str2))  # 输出结果为 <re.Match object; span=(0, 9), match='character'>

Ranges of characters can be indicated by giving two characters and separating them by a '-'

也就是说, 可以在[]中 使用连接符(hyphen, -)来表示某一范围内的字符。例如, [0-9] 表示匹配0到9的某个数字;

也可以 表示多个 范围内的字符。例如, [0-9a-fA-F]表示匹配一个16进制数且大小写不敏感。

如果-被转义或者 位于[]中的第一个或最后一个字符,它将没有表示范围的作用了,仅为一个普通字符-.例如,[a\-z],[-a],[a-]

import re
test_str1 = '渔道创建于2020年5月4日'
RE_SQUARE_BRACKET1 = r'[0-9]'
test_str2 = '3f6c5B'
RE_SQUARE_BRACKET2 = r'[0-9a-fA-F]{2}'
test_str3 = '3f6-c5B'
RE_SQUARE_BRACKET3 = r'[a\-z]'
RE_SQUARE_BRACKET4 = r'[-az]'
RE_SQUARE_BRACKET5 = r'[az-]'
print(re.search(RE_SQUARE_BRACKET1, test_str1)) # <re.Match object; span=(5, 6), match='2'>
print(re.search(RE_SQUARE_BRACKET2, test_str2)) # <re.Match object; span=(0, 2), match='3f'>
print(re.search(RE_SQUARE_BRACKET3, test_str3)) # <re.Match object; span=(3, 4), match='-'>
print(re.search(RE_SQUARE_BRACKET4, test_str3)) # <re.Match object; span=(3, 4), match='-'>
print(re.search(RE_SQUARE_BRACKET5, test_str3)) # <re.Match object; span=(3, 4), match='-'>

Special characters lose their special meaning inside sets. For example, [(+*)] will match any of the literal characters '(', '+', '*', or ')'.

[]中 的特殊字符将会失去 它们的特殊含义。例如,[(+*)] 将匹配 普通字符 '(', '+', '*', ')'

import re
test_str1 = '138*,(hello),3+4'
RE_SQUARE_BRACKET1 = r'[(+*)]'
print(re.search(RE_SQUARE_BRACKET1, test_str1)) # <re.Match object; span=(3, 4), match='*'>
# PS:可以自己修改test_str1的内容,看看匹配结果会发生什么变化

Character classes such as \w or \S (defined below) are also accepted inside a set

[] 中允许使用 如\w or \S 的之类的 特定序列。这些特定序列后面会介绍。

import re
test_str1 = 'python is a programing language'
RE_SQUARE_BRACKET1 = r'[\w]' # \w 表示 字母、数字、下划线
print(re.search(RE_SQUARE_BRACKET1, test_str1)) # <re.Match object; span=(0, 1), match='p'>

Characters that are not within a range can be matched by complementing the set.If the first character of the set is '^', all the characters that are not in the set will be matched.

前面都介绍的是 匹配[]中指定的字符,如果想要做相反的事情,即匹配不在[]中的字符。要怎么做呢?只需要将[]中的第一个字符指定为’^’,那么所有不在[]中的字符都将被匹配。这就是我们前面提到的^的第二个作用,“取反”。如果[]中的^不是第一个字符,它就没有"取反"的作用,仅为普通字符。

import re
test_str1 = 'a54321'
RE_SQUARE_BRACKET1 = r'[^af5]' # 匹配除a,f,5以外的其他字符
print(re.search(RE_SQUARE_BRACKET1, test_str1)) # <re.Match object; span=(2, 3), match='4'>

To match a literal ']' inside a set, precede it with a backslash, or place it at the beginning of the set.

如果要匹配一个']'字符,两种方式:1. 使用反斜杠转义;2. 将]放在字符集的起始位置

import re
test_str1 = '渔道[yudao]'
RE_SQUARE_BRACKET1 = r'[\]]'
RE_SQUARE_BRACKET2 = r'[]]'
print(re.search(RE_SQUARE_BRACKET1, test_str1)) # <re.Match object; span=(8, 9), match=']'>
print(re.search(RE_SQUARE_BRACKET2, test_str1)) # <re.Match object; span=(8, 9), match=']'>

通过学习character class[],我们知道 它是匹配[]中的多个字符中的某一个字符。如果我们想匹配 多个表达式中的一个表达式,能实现吗?of course!

|(alternation)

A|B, where A and B can be arbitrary REs, creates a regular expression that will match either A or B. An arbitrary number of REs can be separated by the '|' in this way. This can be used inside groups (see below) as well. As the target string is scanned, REs separated by '|' are tried from left to right. When one pattern completely matches, that branch is accepted. This means that once A matches, B will not be tested further, even if it would produce a longer overall match. In other words, the '|' operator is never greedy. To match a literal '|', use \|, or enclose it inside a character class, as in [|].

  1. |(vertical bar)的两边是任意的正则表达式;
  2. 任意数量的正则表达式都可以由|连接;
  3. |是non-greedy的,也就是说,当待匹配字符串被正则引擎从左向右扫描时,如果表达式A匹配了,那么表达式B就不再进行匹配操作。其实这有点类似于逻辑运算 ‘或’;
  4. 如果仅匹配普通字符’|’,要么是用反斜杠转义,要么使用方括号将’|'括起来;
import re
test_str1 = 'I like to eat apple'
test_str2 = 'I like to eat apple, banana'
test_str3 = 'I like to eat appl banana'
test_str4 = 'I like to eat appl banan orange'
test_str5 = 'I like to eat apple\|or banana'
RE_ALTERNATION = r'apple|orange|banana'
RE_VERTICAL_BAR = r'[|]'# r'\|'
print(re.search(RE_ALTERNATION, test_str1))
print(re.search(RE_ALTERNATION, test_str2))
print(re.search(RE_ALTERNATION, test_str3))
print(re.search(RE_ALTERNATION, test_str4))
print(re.search(RE_VERTICAL_BAR, test_str5))

第9行输出结果为 <re.Match object; span=(14, 19), match=‘apple’>,说明匹配上了表达式apple。

第10行输出结果为 <re.Match object; span=(14, 19), match=‘apple’>,说明|是non-greedy的。

第11行输出结果为 <re.Match object; span=(19, 25), match=‘banana’>,说明 |有类似逻辑或的含义,当前面的表达式不满足时,会继续测试后面的表达式是否于目标字符串匹配。

第12行输出结果为 <re.Match object; span=(25, 31), match=‘orange’>,说明 |有类似逻辑或的含义,当前面的表达式已匹配时,就不在测试后面的表达式了。

第13行输出结果为 <re.Match object; span=(20, 21), match=’|’>,说明 可以使用\|或者[|]匹配普通字符|

(…)

Matches whatever regular expression is inside the parentheses, and indicates the start and end of a group; the contents of a group can be retrieved after a match has been performed, and can be matched later in the string with the \number special sequence, described below. To match the literals '(' or ')', use \( or \), or enclose them inside a character class: [(], [)].

小括号有两个作用:分组&捕获

  1. 通过将正则表达式的一部分放在小括号中,可以将这一部分匹配的内容分在一个组里;
  2. 生成一个编号的捕获组,该捕获组的内容可以在正则搜索匹配完后被使用;
import re
test_str1 = '反斜杠backslash的作用是转义'
RE_PARENTHESE = r'反斜杠(backslash)'
# RE_PARENTHESE = r'反斜杠backslash' # 如果我们将正则表达式中的圆括号去掉,会发现group(1)没有了
print(re.search(RE_PARENTHESE, test_str1))  # <re.Match object; span=(0, 12), match='反斜杠backslash'>
print(re.search(RE_PARENTHESE, test_str1).group())  # 反斜杠backslash
print(re.search(RE_PARENTHESE, test_str1).group(0)) # 反斜杠backslash
print(re.search(RE_PARENTHESE, test_str1).group(1)) # backslash

这里顺便提一下Match对象,当使用re.match()或re.search()函数做正则匹配时,如果匹配上了,会返回一个match对象。match.group([group1, ])是一个常用的函数,用来获取匹配上的字符串。group()没有指定参数时,表示获取所有匹配的字符串(包含分组中的字符串),group(0)等价于group()。group(1)表示第一个小括号分组捕获的字符串,group(2)表示第二个小括号分组捕获的字符串,依此类推。

结合这个例子,我再描述一下小括号作用。通过将RE_PARENTHESE正则表达式的’backslash’放入小括号中,使得test_str1中的’backslash’匹配上后,会被放在一个分组中;这个被捕获的有效分组可以通过Match对象的group(1)获取。

所以小括号的分组&捕获有两层含义,执行匹配前和执行匹配后,执行匹配前将正则表达式分组,执行匹配后可以单独获取匹配的分组的内容。这里我将(regex)叫做 无名捕获分组,它通过1-99的分组号索引。

(?:…)

A non-capturing version of regular parentheses. Matches whatever regular expression is inside the parentheses, but the substring matched by the group cannot be retrieved after performing a match or referenced later in the pattern.

前面学习了捕获分组,那么 (?:regex)就是非捕获分组。什么意思呢?就是说执行匹配后,不能获取到匹配的分组的内容。

我们将上一个例子稍作修改,将正则表达式改成非捕获分组

import re
test_str1 = '反斜杠backslash的作用是转义'
RE_PARENTHESE = r'反斜杠(?:backslash)'
print(re.search(RE_PARENTHESE, test_str1))  # <re.Match object; span=(0, 12), match='反斜杠backslash'>
print(re.search(RE_PARENTHESE, test_str1).group())  # 反斜杠backslash
print(re.search(RE_PARENTHESE, test_str1).group(0)) # 反斜杠backslash
print(re.search(RE_PARENTHESE, test_str1).group(1)) # IndexError: no such group

执行后发现,第7行报错,"捕获不到"分组的内容。

所以非捕获分组的含义是,仅执行匹配,但不分组也更谈不上单独获取分组的内容

(?P<name>…)

Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name name. Group names must be valid Python identifiers, and each group name must be defined only once within a regular expression. A symbolic group is also a numbered group, just as if the group were not named.

(...)理解了前面学习的捕获分组,那么(?P<name>...)就是有名捕获分组。什么意思呢?前面我提到了捕获分组,在获取匹配上的分组内容时,是通过数字来索引的。而有名捕获分组是通过name来获取匹配上的分组内容。

import re
test_str1 = '反斜杠backslash的作用是转义'
RE_PARENTHESE = r'反斜杠(?P<mygroup>backslash)'
print(re.search(RE_PARENTHESE, test_str1))  # <re.Match object; span=(0, 12), match='反斜杠backslash'>
print(re.search(RE_PARENTHESE, test_str1).group())  # 反斜杠backslash
print(re.search(RE_PARENTHESE, test_str1).group(0)) # 反斜杠backslash
print(re.search(RE_PARENTHESE, test_str1).group(1)) # backslash
print(re.search(RE_PARENTHESE, test_str1).group('mygroup')) # backslash

这个例子,我将第3行的正则表达式改成了 (?P<mygroup>backslash) ,前括号`<>中的name可以任意取名,我这里使用了 mygroup。然后在第8行,使用group(‘mygroup’) 获取匹配上的分组内容(backslash)。

综上所示,(?P<name>...)就是可以通过name来获取匹配分组的内容。

反引用(backreference)

Backreferences match the same text as previously matched by a capturing group

反引用有两种,一种是无名反引用,一种是有名反引用。类似于捕获分组和有名捕获分组

无名反引用

无名反引用的语法是 \number,number是1-99的数字。表示 匹配 前面对应数字的捕获分组 的内容

import re
test_str1 = 'yudao is a good platform to learn python, do you want to learn python?'
RE_BACK_REFERENCE = r'(?:.*?)(python)(?:.*?)(\1)(?:.*?)'
print(re.findall(RE_BACK_REFERENCE, test_str1)) # 输出结果 [('python', 'python')]

第3行的正则中,使用了分组捕获(python),使用了反引用\1,同时对其加上了一对小括号表示也要捕获它的内容。这个正则的逻辑是 获取test_str1中的两个python。它的实际运行结果也是 输出了两个 ‘python’。使用反引用的好处就是,可以复用前面的捕获分组信息,只需表达清楚使用第几组分组\number即可

有名反引用

有名反引用的语法是 (?P=name),也就是复用前面的有名分组。

import re
test_str1 = 'yudao is a good platform to learn python, do you want to learn python?'
RE_BACK_REFERENCE = r'(?:.*?)(?P<aa>python)(?:.*?)((?P=aa))(?:.*?)'
print(re.findall(RE_BACK_REFERENCE, test_str1)) # 输出结果 [('python', 'python')]

ok,这7中语法就介绍到这里,你是否学到了呢?如果有所收获,欢迎关注、评论、点赞。

python之正则表达式2相关推荐

  1. Python中正则表达式用法 重点格式以这个为准_首看_各种问题

    20210811 https://www.jb51.net/article/101258.htm 一.惰性模式的概念: 此模式和贪婪模式恰好相反,它尽可能少的匹配字符以满足正则表达式即可,例如: va ...

  2. python使用正则表达式判别字符串是否以一个大写字符起始而跟随了一些小写字符

    python使用正则表达式判别字符串是否以一个大写字符起始而跟随了一些小写字符 # # Python3 code to find sequences of one upper # case lette ...

  3. python使用正则表达式统计字符串中出现次数最多的数字

    python使用正则表达式统计字符串中出现次数最多的数字 #python使用正则表达式统计字符串中出现次数最多的数字 # find the most occurring element import ...

  4. python使用正则表达式识别大写字母并在大写字母前插入空格

    python使用正则表达式识别大写字母并在大写字母前插入空格 #python使用正则表达式识别大写字母并在大写字母前插入空格 import redef putSpace(input):# regex ...

  5. python使用正则表达式删除字符串中的其它字符只保留数字和字母

    python使用正则表达式删除字符串中的其它字符只保留数字和字母 #python使用正则表达式删除字符串中的其它字符只保留数字和字母 # Python code to demonstrate # to ...

  6. python使用正则表达式寻找具有特定后缀的文件

    python使用正则表达式寻找具有特定后缀的文件 # python使用正则表达式寻找具有特定后缀的文件 # import library import re# list of different ty ...

  7. python使用正则表达式抽取字符串中最大数值数字

    python使用正则表达式抽取字符串中最大数值数字 #python使用正则表达式抽取字符串中最大数值数字 # Function to extract maximum numeric value fro ...

  8. python使用正则表达式去除句子中的重复词

    python使用正则表达式去除句子中的重复词 #python使用正则表达式去除句子中的重复词 # Python program to remove duplicate words # using Re ...

  9. python使用正则表达式检测给定的URL地址是否合法

    python使用正则表达式检测给定的URL地址是否合法 # python使用正则表达式检测给定的URL地址是否合法 # python使用正则表达式检测给定的URL地址是否合法 # Check if a ...

  10. python使用正则表达式验证邮箱地址语法有效性

    python使用正则表达式验证邮箱地址语法有效性 #python使用正则表达式验证邮箱地址语法有效性 import re # mail regular expression formula# rege ...

最新文章

  1. UVa11452 Dancing the Cheeky-Cheeky(kmp)
  2. MorGain2020中文版
  3. 模糊数学笔记:六、模糊模型识别-I(最大隶属度原则)
  4. Linux服务器网页显示乱码
  5. 关于Python的编码注释# -*- coding:utf-8 -*- 详解
  6. android 动态修改控件的宽高
  7. java地图点线面_openlayers之点,线,面(以城市,河流,省份为例,分别对应点线面)...
  8. NS 802.11函数分析(一)
  9. uos配置 java 环境变量_CentOS 7.3 环境配置java和tomcat开机启动
  10. 20-21-2网络管理quiz5
  11. delphi编写ocx控件步骤
  12. stc单片机id加密c语言,STC单片机内部ID读取
  13. 十大排序方法之基数排序
  14. Julia Computing获得 2400 万美元融资,前 Snowflake CEO 加入董事会
  15. 前端静态资源缓存最优解以及max-age的陷阱
  16. web前端学习之——页面美妆师css3基础篇
  17. 如何在CentOS 7中设置或更改主机名
  18. Adaptive Server Anywhere 数据库配置ODBC数据源
  19. 平价的无线蓝牙耳机,性价比高的无线蓝牙耳机
  20. linux 中read命令后面-p是什么意思呢

热门文章

  1. javaweb JAVA JSP汽车配件销售系统jsp配件销售网站 (jsp电子商务系统,购物商城)在线购物案例
  2. Objective-C中的消息发送总结
  3. 1. 计算机网络和因特网
  4. 你误把饥渴当成了爱情
  5. 手机测试磁场的软件,男子用手机软件检测出自家卧室床上电磁辐射爆表
  6. 张飞老师硬件第十六部视频整理——硬件基础2
  7. LeetCode题解(面试10.11):峰与谷(Python)
  8. 通过AI实现实时数据分析和态势监测,进而让机器能够处理日常决策
  9. 特征选择之方差选择法VarianceThreshold
  10. fetch用英语解释_fetch的用法总结大全