Python学习笔记:正则表达式基础入门指南

一.正则表达式简介

正则表达式(Regex)用来查找和匹配字符串中的模式。可以把它看作是一种“搜索”工具,帮助找到特定的字符或字符串,表1给出一些常见的特殊字符应用:

表1 特殊字符在正则化表达式的应用

字符

作用

.

匹配除换行符以外的任何单个字符

\d

匹配任何数字字符

\D

匹配任何非数字字符

\w

匹配任何字母数字字符(包括下划线)

\W

匹配任何非字母数字字符(不包括下划线)

\s

匹配任何空白字符(包括空格、制表符、换行符等)

\S

匹配任何非空白字符

^

匹配字符串的开始位置

$

匹配字符串的结束位置

*

匹配前面的字符0次或多次

+

匹配前面的字符1次或多次

?

匹配前面的字符0次或1次

{m}

匹配前面的字符m次

{m,n}

匹配前面的字符至少m次,至多n次

一般来说,通常的代码可以写作:

pattern = r'\b\w+\b'

r 前缀让Python将字符串中的反斜杠视为普通字符,而不是转义符

二.Re模块

2.1Re.match()函数

re.match()函数从字符串起始位置开始匹配

re.match(pattern,string,flags=0)

其中pattern是匹配的正则表达式,string是待匹配的字符串,flags是控制位,用来控制匹配方式。

若string中的字符串和pattern中的正则表达式匹配,就返回匹配值,输出开始和起始位置。

下面给出匹配示例:

import re

print(re.match('a','abstract').span())
print(re.match('ab','abstract').span())
print(re.match('b','abstract'))

使用相关字符去匹配字符串,得到结果输出如下:

(0, 1)
(0, 2)
None

2.2Re.search()函数

Re.search函数会匹配整个字符串,若string中的字符串和pattern中的正则表达式匹配,就返回匹配值

re.search(pattern,string,flags=0)

匹配结果和match函数相同,成功则返回输出位置,失败则返回None

import re

print(re.search('a','abstract').span())
print(re.search('ab','abstract').span())
print(re.search('b','abstract').span())
print(re.search('rac','abstract').span())
print(re.search('e','abstract'))

得到结果如下:

(0, 1)
(0, 2)
(1, 2)
(4, 7)
None

2.3Re.sub()函数

re.sub()函数用以替换字符串的匹配项

re.sub(pattern, repl, string)

pattern是要匹配的正则表达式模式,repl是替换的内容,可以是一个字符串或函数,string是被处理的原始字符串。

2.4re.compile()函数

re.compile(pattern, flags=0)

re.compile() 函数作用是可以将编译后的正则表达式对象存储在一个变量中,并多次使用它进行匹配

三.贪婪模式与非贪婪模式

贪婪模式会尽可能多地匹配字符,直到整个正则表达式都能匹配成功为止。

*

匹配前面的字符0次或多次

+

匹配前面的字符1次或多次

?

匹配前面的字符0次或1次

{m,n}

匹配前面的字符至少m次,至多n次

非贪婪模式与贪婪模式相反,它会尽可能少地匹配字符

比较贪婪模式,非贪婪模式会多一个字符"?"区分

*

匹配前面的字符0次或多次,但尽可能少地匹配

+

匹配前面的字符1次或多次,但尽可能少地匹配

?

匹配前面的字符0次或1次,但尽可能少地匹配

{m,n}

匹配前面的字符至少m次,至多n次,但尽可能少地匹配

四.相关练习

4.1解析北美地区电话号码

电话号码有一个3位数的区号和一位7位数的号码组成(这个7位数有分成一个3位的局号和一个4位的路号,局号和路号之间使用连字符分隔) 每位电话号码可以是任意数字,但是区号和局号的第一位数字不能是0或1。实际书写号码是往往会把区号写在括号里面,或者将区号使用连字符和后面的局号连接起来。例如:(313)555-1234或313-555-1234,有时候在括号你里面会包含空格。例如:(313 )555-1234

解析:开始和结束使用^和$;区号的括号可选可不选,使用\(?和\)?匹配;由于区号和局号首位数字不能为0或1,使用[2-9]匹配;对于后续位数数字使用\d{m}表示匹配m次数字;由于括号里面可能包含空格,使用\s?匹配,若是多位空格则需把?改为*,本题应只为?;后面可能没有括号()而是直接使用"-"符号,使用-?表示匹配,同理后续局号和路号的处理也用[2-9]和\d{m}处理。

pattern=r'^\(?[2-9]\d{2}\s?\)?-?[2-9]\d{2}-\d{4}$'

测试

import re

pattern=r'^\(?[2-9]\d{2}\s?\)?-?[2-9]\d{2}-\d{4}$'
numbers = [
    "(313)555-1234",
    "(810 )555-1234",
    "248-555-1234",
    "055-123-1234",  
    "155-123-1234",  
    "555 123 1234"   
]

for i in numbers:
    if re.match(pattern, i):
        print(f"{i} 是有效的电话号码。")
    else:
        print(f"{i} 不是有效的电话号码。")

输出

(313)555-1234 是有效的电话号码。
(810 )555-1234 是有效的电话号码。
248-555-1234 是有效的电话号码。
055-123-1234 不是有效的电话号码。
155-123-1234 不是有效的电话号码。
555 123 1234 不是有效的电话号码。

参考

1.正则表达式指南 — Python 3.13.3 文档

2.解析各类电话号码、邮政编码及邮箱地址的正则表达式-CSDN博客

作者:孜宸润泽

物联沃分享整理
物联沃-IOTWORD物联网 » Python学习笔记:正则表达式基础入门指南

发表回复