首页 > 编程语言 >正则表达式快速入门三: python re module + regex 匹配示例

正则表达式快速入门三: python re module + regex 匹配示例

时间:2023-01-06 23:33:56浏览次数:53  
标签:regex search group 示例 re print 匹配

使用 Python 实现不同的正则匹配(从literal character到 其他常见用例)

reference python regular expression tutorial

  • 目录

    • importing re
    • literal characters(basic/ordinary characters)
    • wild/special characters
    • repetitions
    • groups and named groups
    • greedy vs. non-greedy matching

PS : 这个教程涵盖了正则表达式中的一些基本概念,展示了部分re中函数接口的使用, 如 compile() search() findall() sub() split() 等

正则表达式有不同的实现方式(regex flavors): python的 regex engine也只是其中的一种(very modern and complete), 因此可能存在部分正则表达式的mode或者feature python并不支持

import re

import re

Ordinary character(Literal character)

字对字的匹配

除了正则表达式中的特殊字符(metacharacter),大多数字符都会与其自身匹配; 而对于特殊字符如果想要将其按照原义匹配,需要使用反斜杠进行转义

pattern = r"regex"
sequence = "regex"

if re.search(pattern, sequence):
    print("Match!")
else: print("Not a Match!")
Match!
pattern = r"\\"
sequence = "\\abc"

if re.search(pattern, sequence):
    print("Match!")
else: print("Not a Match!")
Match!

Wild Card Characters: special characters

正则表达式中的特殊字符的用法

# .(dot)
# wildcard (dot match everything)
# search 和group 的用法在之前说过
re.search(r're.ex', 'regex').group()
'regex'
#  ^(caret)   
# anchor 的一种,指定匹配的位置(at the start of the string)
# 如果你想要确认一段文本或者一个句子是否以某些字符打头,那么^ 是有用的
print(re.search(r"^regex", "regex is powerful").group())

# 而下面这行代码就会报错 :NoneType' object has no attribute 'group'
# print(re.search("^regex", "Let's learn the regex").group())
regex
# $ (dollor character)
# 也是另一种anchor 从末尾开始匹配
# 如果你想确定文本是否以某些character 结尾, 那么$是有用的
print(re.search(r"regex$", "Let's learn the regex").group())

# 而下面这行代码就会报错 :NoneType' object has no attribute 'group'
# print(re.search("regex$", "regex is powerful").group())

regex
# [](character class): 字符集
# [^]: characters that are not within a class : 取非

print(re.search(r"regex: [A-Za-z0-9]", "regex: a").group())
print(re.search(r"regex: [A-Za-z0-9]", "regex: A").group())
print(re.search(r"regex: [A-Za-z0-9]", "regex: 0").group())
print(re.search(r'regex: [^A-Za-z0-9]', "regex: @").group())
regex: a
regex: A
regex: 0
regex: @
# \ Backslash
# 1. 反斜杠可以用在所有特殊字符之前以去掉其特殊含义
# 2. 如果在反斜杠后的字符是一个合法的转义字符,那么他们组成一个具有特殊含义的term  如\d 表示数字字符;如果非法,那么反斜杠将被看做一个普通字符

# 情况一
print(re.search(r"\\d", "\d regexex").group())

# 情况二
print(re.search(r"\d", "2 regexex").group())
\d
2
# 一些以 反斜杠打头的 special sequence
# \w \d \s

# 1. \w:匹配任意的单个字母,数字,或者下划线  \W  匹配无法被 \w匹配的任意字符
# 注:可以通过修改 match flag 来改变\w的范围
print("小写w:", re.search(r"re\we\w", "regex").group())
print("大写W:", re.search(r"re\We\W", "re&e@").group())
小写w: regex
大写W: re&e@
# 也可以尝试其他不同的特殊字符
# \s 表示一个单独的空格 character: 包括 space ,newline, tab ,return
# \S 对 \s 代表的 character class 取非

# \d 表示 数字 0-9 
# \D 对 \d 取非

# 对应的大写为取非,接下来仅介绍小写
# \t :tab
# \n :newline
# \r : return

# 还有一些常用的anchor
# \A:  只在字符串的开头进行匹配,跨多行工作(Works across multiple lines as well.)
# \Z: 只在字符串的末尾进行匹配

# 上述和前面介绍的 ^ $ 在功能上是相同的, 区别在于 他们如何处理 MULTLLINE mode
# \b :只在字符串的开头或者结尾进行匹配

Repetition

前面都是字符层次的匹配,为了拓展匹配的范围,接下来展示 正则表达式中的重复

在前面所述的 \d 这一类字符后 使用 + 或者* 可以匹配一长串数字,网址等。两者的功能: check 是否前一个字符出现了0次或者多次(即是否存在重复)

?:检查前一个字符是否出现过;也即问号前的字符 在 目标字符串中可不存在

{}用于指定重复的次数

{x}: 重复 x 次
{x, }: 至少重复x次
{x, y}: 重复至少x 次 ,至多 y 次

re.search(r"\d{3}", "999").group()
'999'
re.search(r"\d{2,4}", "9999").group()
'9999'

grouping in regex

capturing group 是正则表达式的特性之一, 表达式中由一对圆括号括起来的部分被称为group}

group 不会改变匹配的结果,但它将会将匹配的一部分字符串组成一个 capturing group 对象,可以使用index进行索引,也可以对group对象进行命名

之前.group() 函数默认返回整个匹配的结果, 如果未在正则表达式中对group进行命名,那么可以使用从左到右的数字索引,如果命名之后,那么可以使用 名字做索引

假如你想要验证邮件地址,并且检查 name 和 host, 这个时候分组是有好处的

在存在 group 时, re库的一些常用函数的返回值会有特殊的形式,详情请见前一篇文章

statement = "please contact us at : [email protected]"
match = re.search(r"([\w\.-]+)@([\w\.-]+)", statement)

if statement:  # 如果待校验邮件地址非空
    print("邮件地址:", match.group())  
    print("用户名:", match.group(1))
    print("Host:", match.group(2))
邮件地址 [email protected]
用户名 regex_helper
Host wclsn.com
# namedgroups :语法 ?P<name>
match = re.search(r'(?P<email>(?P<username>[\w\.-]+)@(?P<host>[\w\.-]+))', statement)

if statement:
    print("邮件地址:", match.group('email'))  
    print("用户名:", match.group('username'))
    print("Host:", match.group('host'))

邮件地址: [email protected]
用户名: regex_helper
Host: wclsn.com

greedy or non-greedy matching

贪婪匹配或者 非贪婪匹配

前者: .(dot match everything) + * :也即尽可能的进行匹配

# 贪婪匹配并不总是好的
#匹配一个 html tag的前半部分
heading = r"<h1>TITLE</h1>"
re.match(r'<.*>', heading).group()
'<h1>TITLE</h1>'
# 解决方案一 采用准确的character class
print( re.match(r'<[A-Za-z][\w]*>', heading).group() )

# 解决方案二  使用 greedy qualifer *? (这个量词的作用是进行字符数尽可能少的匹配)
print( re.match(r'<.*?>', heading).group() )

<h1>
<h1>

flag value(前面提到过)

re.I (IGNORECASE):正则表达式匹配时忽略大小写

re.S(DOTALL): dot match everything(including newline)

re.M(MULTILINE): Allows start of string (^) and end of string ($) anchor to match newlines as well.

re.X(re.VERBOSE):允许在正则表达式中写whitespace和注释以提升表达式的可读性

statement = "Please contact us at: [email protected], [email protected]"

# Using the VERBOSE flag helps understand complex regular expressions
pattern = re.compile(r"""
[\w\.-]+ #First part
@ #Matches @ sign within email addresses
[\w\.-]+  # host
""", re.X | re.I)

addresses = re.findall(pattern, statement)                       
for address in addresses:
    print("Address: ", address)
Address:  [email protected]
Address:  [email protected]

以上就是本次教程的主要内容,主要是将第一次教程中所介绍的正则表达式的基本概念与第二次教程中所介绍的python re module 的函数接口结合到一起,具体的去说明python中的正则匹配。其实正则表达式可以使用的空间很广,并不一定要拘泥于python,如常见的文本编辑器往往支持正则查找与匹配(vscode vim等)还有很多可以使用到正则表达式的应用,因此学习瓶颈往往在正则表达式的书写,而不在使用的编程语言。只有在实践中不断的使用正则表达式并积累经验,才可以真正的做到从心所欲不逾矩。

标签:regex,search,group,示例,re,print,匹配
From: https://www.cnblogs.com/wclsn-blog/p/17031926.html

相关文章

  • 正则表达式快速入门二 :python re module 使用
    pythonregexmodulere使用referenceregexmoduleinpythonimportrere.searchre.search(regex,subject,regex_matching_mode):applyaregexpetterntoasub......
  • response下载文件
    Servlet实现文件下载一. servlet项目创建1. 新建maven项目新建maven项目记得更换jdk版本项目设置在模块那添加web编译配置添加本地tomcat运行如......
  • 惊呆了!谷歌Daydream虚拟现实头显售价仅79美元
    据外媒报道,谷歌将于10月4日举办新品发布会。消息人士表示,此次发布会上亮相的除了是两款旗舰智能机,可能还将包括Daydream虚拟现实头显。谷歌已经与多家公司展开合作......
  • redhat创建bond
    如果有问题关闭NetworkManager注意三个网卡配置文件要注释掉uuid,并且配置文件中不相干的参数要注释或删除掉1、创建bond0文件vim/etc/sysconfig/network-scripts/ifcf......
  • 验证功能访问Redis的次数和命令
    背景公司内部在进行性能调优,调优有多个方法.应用Redis方面主要的调优有:1.进行redis键值对大小的处理.2.进行redis键值对过期时间的处理.3.减少连接数,减少网络......
  • 正则表达式快速入门一 :regex 的基本概念及语法特性
    Regexquickstart:正则表达式快速入门author:wclsnreferencequickstart如果想要了解正则表达式的基本概念且英文ok的话,完全可以从我上面所附网站的quickstart看起......
  • Forexclu认为不仅中国希望石油人民币化,一些国家也希望如此
    石油行业的去美元化不仅是中东国家希望看到的,也是中国所期望的。因为中东国家希望石油多元化,避免以后自己的命门被西方国家所掌控。OPEC+成员国的已探明石油储量中,约40%......
  • MaoWei-2020-HistoryRepeatsItself-ECCV
    HistoryRepeatsItself:HumanMotionPredictionviaMotionAttention#paper1.paper-info1.1MetadataAuthor::[[WeiMao]],[[MiaomiaoLiu]],[[MathieuSal......
  • k8s 1.22.10 Ingress-nginx 的部署
    1.创建ingressingress-nginx/index.mdatcontroller-v1.1.3·kubernetes/ingress-nginx(github.com)源文件地址:ingress-nginx/index.mdatcontroller-v1.1.3·ku......
  • dremio 系统内部存储插件与自定义存储插件加载的区别
    dremio整体包含了两大类存储扩展,系统内部使用的,以及用户开发的,整体区别系统的目前是在dremio自己启动的时候就会注册以及使用的,比如加速反射的,home,元数据存储插件用......