首页 > 编程语言 >Python正则表达式

Python正则表达式

时间:2022-11-25 15:03:53浏览次数:59  
标签:__ regex search 匹配 Python 正则表达式 print group

在登录某些网站时,需要填写邮箱等相关信息,在邮箱格式填错时,页面总能第一时间检出并告知用户邮箱格式有误,那么程序员是使用什么方法实现这种检测的呢?一般会使用正则表达式。正则表达式定义了字符串的匹配模式,即如何检查一个字符串是否有跟某种模式匹配的部分或者从一个字符串中将与模式匹配的部分提取出来或者替换掉。Python 也提供了对正则表达式操作的支持, Python 通过标准库中的 re 模块来支持正则表达式操作。


1

查找第一次出现的匹配文本


    首先,通过一个例子来看看如何在 Python 中使用正则表达式查找文本模式。假设我们需要在一个字符串中查找是否包含国内的一个座机号码,格式为  XXX-XXXXXXX  ,即三个数字表示区号,加上一个短横杠,加上七个数字表示座机号。


# 导入正则表达式模块
import re
if __name__ == '__main__':
phoneNumRegex = re.compile(r'\d\d\d-\d\d\d\d\d\d\d')
mo = phoneNumRegex.search('My number is 020-1234567.')
print('Phone number is: ' + mo.group())


最终输出为

Phone number is: 020-1234567


    我们来解释一下上面的代码。Python 中的所有正则表达式的函数都在 re 模块中,所以使用正则表达式时一定要导入 re 模块。在程序中调用 compile() 方法,通过传入一个正则表达式字符串,返回一个 Regex 模式对象。通过这个模式对象调用 search() 方法,传入字符串,以查找正则表达式的所有匹配。如果在此字符串没有找到匹配正则表达式的文本,该方法会返回 None 。如果找到了匹配项,该方法会返回一个 Match 对象。Match 对象中有 group() 方法,它返回被查找字符串中实际匹配的文本。在这个例子中,我们将正则表达式传入 re.compile() ,\d代表一个数字字符,并将得到的 Regex 对象保存到 phoneNumRegex 中,通过调用 search() 方法,传入想要进行查找的文本,把查找的结果放在 mo 变量中,因为文本里面刚好有匹配的文本,所以最终返回了一个 Match 对象,最后通过调用 group() 方法返回匹配的结果。


2

匹配文本的不同部分


    如果我们想要把区号和座机号进行分离,可以在正则表达式中添加括号以示分组,从而获得匹配文本的不同部分。


import re
if __name__ == '__main__':
phoneNumRegex = re.compile(r'(\d\d\d)-(\d\d\d\d\d\d\d)')
mo = phoneNumRegex.search('My number is 020-1234567.')
print('Phone number is: ' + mo.group())
print(mo.groups())
print('Area code: ' + mo.group(1))
print('Phone number: ' + mo.group(2))


最终输出为

Phone number is: 020-1234567

('020', '1234567')

Area code: 020

Phone number: 1234567


    可以看到,我们使用了两对括号对区号和座机号进行了分组。调用 groups() 方法可以一次性获取到所有的分组,这些分组的值存放在元组中。向 group() 方法传入 0 或者 不传入参数,将返回整个匹配的文本;而传入组号则能获取相应组的文本(组号从1开始)。


3

匹配特殊的字符


在正则表达式中,下面的字符都具有特殊的含义:

.   ^   $   *   +   ?   {   }   [   ]   \   |   (   )

如果要匹配实际的字符,需要加 \ 对其进行转义。

\.   \^   \$   \*   \+   \?   \{   \}   \[   \]   \\   \|   \(   \)


下面的例子演示了如何在文本中匹配特殊的字符。

import re
if __name__ == '__main__':
regex = re.compile(r'\(1\+2\)')
mo = regex.search('3*(1+2)=9')
print(mo.group())


最终输出为

(1+2)



4

用管道匹配多个项中的一个


    如果希望匹配多个项中的一个时,可以使用管道符号 | 。使用此符号只能匹配第一次出现的匹配文本。下面的例子演示了如何匹配 'Mary' 或 'Tom' 其中的一个。

import re
if __name__ == '__main__':
regex = re.compile(r'Mary|Tom')
mo = regex.search('Hello, I am Mary. This is my friend Tom.')
print(mo.group())


最终输出为第一次出现的匹配文本

Mary



5

用问号匹配可选项


    如果你希望匹配一段文本,但其中部分字符是可以存在也可以不存在的,可以使用 ? 。? 表明前面的分组在这个模式中是可选的。

import re
if __name__ == '__main__':
regex = re.compile(r'B(an)?')
mo1 = regex.search('B')
print(mo1.group())
mo2 = regex.search('Ban')
print(mo2.group())


最终输出为

B

Ban



6

用星号匹配零次或多次出现的文本


    如果你希望匹配的文本,其中部分内容可以不出现,也可以出现一次或重复出现多次,则可以使用 * 。

import re
if __name__ == '__main__':
regex = re.compile(r'B(an)*')
mo1 = regex.search('B')
print(mo1.group())
mo2 = regex.search('Ban')
print(mo2.group())
mo3 = regex.search('Banana')
print(mo3.group())


最终输出为

B

Ban

Banan



7

用加号匹配一次或多次出现的文本


如果你希望匹配的文本,其中部分内容一定要至少出现一次,则可以使用 + 。

import re
if __name__ == '__main__':
regex = re.compile(r'B(an)+')
mo1 = regex.search('B')
print(mo1 is None)
mo2 = regex.search('Ban')
print(mo2.group())
mo3 = regex.search('Banana')
print(mo3.group())


最终输出为

True

Ban

Banan



8

用大括号匹配特定次数



如果你希望匹配的文本,其中部分内容一定要出现特定的次数,则可以使用 {} 。

import re
if __name__ == '__main__':
regex = re.compile(r'B(an){1}')
mo1 = regex.search('B')
print(mo1 is None)
mo2 = regex.search('Ban')
print(mo2.group())
mo3 = regex.search('Banana')
print(mo3.group())


最终输出为

True

Ban

Ban


    当然,我们也可以在 {} 中指定这部分内容出现次数的范围。例如要匹配 'Cz' 至少出现2次,至多出现5次,正则表达式写为 (Cz){2,5} ,则字符串 'CzCz' 'CzCzCz' 'CzCzCzCz' 'CzCzCzCzCz' 都符合匹配规则。

import re
if __name__ == '__main__':
regex = re.compile(r'(Cz){2,5}')
mo1 = regex.search('Cz')
print(mo1 is None)
mo2 = regex.search('CzCz')
print(mo2.group())
mo3 = regex.search('CzCzCzCzCz')
print(mo3.group())
mo4 = regex.search('CzCzCzCzCzCz')
print(mo4.group())


最终输出为

True

CzCz

CzCzCzCzCz

CzCzCzCzCz



9

查找所有匹配的文本


    如果你希望获得所有匹配的文本,可以使用 Regex 对象的 findall() 方法。如果在正则表达式中没有分组,该方法将会返回一个字符串列表;如果在正则表达式中有分组,该方法会返回一个字符串的元组的列表,每个分组对应一个字符串。

import re
if __name__ == '__main__':
regex = re.compile(r'\d\d\d-\d\d\d\d\d\d\d')
mo1 = regex.findall('Tom: 020-1122334 Mary: 010-2233445')
print(mo1)
regex = re.compile(r'(\d\d\d)-(\d\d\d\d\d\d\d)')
mo2 = regex.findall('Tom: 020-1122334 Mary: 010-2233445')
print(mo2)

最终输出为

['020-1122334', '010-2233445']

[('020', '1122334'), ('010', '2233445')]



10

不区分大小写的匹配


    如果你希望在匹配时不区分大小写,可以在 compile() 方法传入第二个参数 re.IGNORECASE 或 re.I。

import re
if __name__ == '__main__':
regex = re.compile(r'python', re.IGNORECASE)
mo1 = regex.search('PYTHON')
print(mo1.group())


最终输出为

PYTHON



11

替换字符串


    如果你希望把匹配的字符串进行替换,可以使用 sub() 方法,第一个参数为要替换成的字符串,第二个参数为一个字符串。

import re
if __name__ == '__main__':
regex = re.compile(r'Mary')
print(regex.sub('Tom', 'Mary is my friend. Mary is 20 years old.'))


最终输出为

Tom is my friend. Tom is 20 years old.



12

正则表达式模式语法中的特殊元素

符号

说明

.

匹配任意字符

^

匹配字符串的开始

$

匹配字符串的结束

[]

匹配来自字符集的任意单一字符

[^]

匹配不在字符集中的任意单一字符

*

匹配0次或多次

+

匹配1次或多次

?

匹配0次或1次

{N}

匹配N次

{M,}

匹配至少M次

{M,N}

匹配至少M次至多N次

A|B

匹配A或B

(exp)

匹配括号内的表达式,也表示一个组

(?:exp)

匹配exp但是不捕获匹配的文本

(?#)

注释

(?=exp)

匹配exp前面的位置

(?!exp)

匹配后面不是exp的位置

(?>exp)

匹配的独立模式,省去回溯

(?<=exp)

匹配exp后面的位置

(?<!exp)

匹配前面不是exp的位置

\w

匹配字母/数字/下划线

\W

匹配非字母/数字/下划线

\s

匹配空白字符(包括\r、\n、\t等)

\S

匹配非空白字符

\d

匹配数字

\D

匹配非数字

\A

匹配字符串开始

\Z

匹配字符串结束,只匹配到换行前的结束字符串

\z

匹配字符串结束

\G

匹配最后匹配完成的位置

\b

匹配单词的边界

\B

匹配非单词边界

\n,\t等

匹配一个换行符,匹配一个制表符等

\1...\9

匹配第n个分组的内容

\10

匹配第n个分组的内容,如果它已经匹配,否则指的是八进制字符码的表达式

(?<name>exp)

匹配exp并捕获到名为name的组中

*?

重复任意次,但尽可能少重复

+?

重复1次或多次,但尽可能少重复

??

重复0次或1次,但尽可能少重复

{M,N}?

重复M到N次,但尽可能少重复

{M,}?

重复M次以上,但尽可能少重复


Python正则表达式_python

更多内容请关注

Python正则表达式_python



标签:__,regex,search,匹配,Python,正则表达式,print,group
From: https://blog.51cto.com/u_15891283/5886735

相关文章

  • 【Python】第4章-12 求满足条件的斐波那契数
    斐波那契数,亦称之为斐波那契数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……,这个数列从第3项开始,每一项都等于前两项之和。求大于输入数的最小斐波那契数。输入格......
  • 使用 pytest 进行 python 脚本测试
    PytestTIPSpytest-tutorial[tips.1]pytest会执行指定目录下所有Test开头的类和函数默认为运行目录,可以通过--rootdir参数指定[tips.2]可以通过assert断言......
  • Python第十章实验
    实例一:创建并打开记录蚂蚁庄园动态的文件实验代码:print("\n","="*10,"蚂蚁庄园动态","="*10)file=open('message.txt','w')print("\n即将显示……\n")实验结果:......
  • Python 处理 Excel 表格
    安装 openpyxl 模块    在Python中没有自带的处理Excel表格的模块,所以我们在Windows上使用 ​​pipinstall--useropenpyxl​​​ 命令安装第三方模块 ​​......
  • Python 操作压缩文件
        我们经常使用压缩程序对文件进行压缩打包,在Python中也提供了相应的zipfile模块方便我们对ZIP压缩文件进行操作。读取 ZIP 压缩文件    读取ZIP压缩文......
  • Python 文件路径
    获取主目录提到文件路径问题,不得不先提一下不同操作系统上文件夹之间的分隔符。在Windows操作系统上,路径的写法采用的是 \ 反斜杠。而在macOS和Linux操作系统上,路径......
  • 使用 Python 组织文件
        在 Python 中, shutil 模块还提供了一系列对文件和文件集合的高级操作。特别是提供了一些支持文件拷贝和删除的函数。下面介绍一些组织文件常用操作。复制文件 ......
  • Python入门(9)——函数
    函数是带名字的代码块,用于完成特定的任务,当在程序中多次执行同一任务时,无需反复编写重复的代码块,只需调用执行该任务的函数即可。函数的声明    在Python中使用 def ......
  • Python入门(10)——类
    在Python中,一切都是对象,对象是类的实例,类是对象的蓝图和模板。类是一个抽象的概念,对象是一个类具体的实例。每个对象都有属性和行为,它们都是独一无二的,而且对象一定属于某个......
  • Python入门(8)——集合
    集合的创建    集合是由不重复元素组成的无序容器。创建集合用 {} 大括号或 set() 函数。注意,创建空集合只能用 set() ,不能用 {} , {} 创建的是空字典。......