Python中使用正则表达式

使用正则表达式处理字符串,能更加高效和简介。 首先,需要导入模块re

import re

常用的元字符:

  1. . 匹配除 “\n” 和 “\r” 之外的任何单个字符。
  2. ^ 匹配字符串开始位置。
  3. $ 匹配字符串中结束的位置。
  4. * 前面的原子重复 0 次、1 次、多次。
  5. ? 前面的原子重复 0 次或者 1 次。
  6. + 前面的原子重复 1 次或多次。
  7. {n} 前面的原子出现了 n 次。
  8. {n,} 前面的原子至少出现 n 次。
  9. {n,m} 前面的原子出现次数介于 n-m 之间。
  10. ( ) 分组,输出需要的部分。

常用的通用字符:

  1. \s 匹配空白字符。
  2. \w 匹配任意字母/数字/下划线。
  3. \W 和小写 w 相反,匹配任意字母/数字/下划线以外的字符。
  4. \d 匹配十进制数字。
  5. \D 匹配除了十进制数以外的值。
  6. [0-9] 匹配一个 0~9 之间的数字。
  7. [a-z] 匹配小写英文字母。
  8. [A-Z] 匹配大写英文字母。
search 第一个匹配串

找出子串第一个匹配位置。

se_str = 'i love you but just love you'
se_pat = 'love'
se_re = re.search(se_pat, se_str)
print(se_re)
print(se_re.span())

输出结果:

<re.Match object; span=(2, 6), match='love'>
(2, 6)
match

match与search匹配字符串不同:

  • match 在原字符串的开始位置匹配。
  • search 在字符串的任意位置匹配。
m_str = 'i love you'
re_com = re.compile('you')
print(re_com.match(m_str))
print(re_com.search(m_str).span())

输出结果:

None
(7, 10)

如果字符串为’you are my sunshine’,'you are my destiny’等,就能使用match匹配到’you’了。

finditer 匹配迭代器

返回所有子串匹配位置的迭代器。

fdr_str = 'i love you but just love you'
fdr_pat = 'love'
fdr_r = re.finditer(fdr_pat, fdr_str)
for i in fdr_r:
    print(i)

输出结果:

<re.Match object; span=(2, 6), match='love'>
<re.Match object; span=(20, 24), match='love'>
findall 所有匹配

findall 方法能查找出子串的所有匹配。

原字符串:

fda_str = '3号楼一单元1001,水费100.56'

目标是查找所有数字,所以需要使用正则表达式。

# r 去除转义字符
fda_pat = r'\d+'
fda_r = re.findall(fda_pat, fda_str)
for i in fda_r:
    print(i)

输出结果:

3
1001
100
56

水费 100.56 ,这里却分开显示,去掉了小数点,所以没有完成我们想要的效果。

匹配浮点数和整数

.? 表示匹配小数点(.)0 次或 1 次

因此,正则表达式可以修改成: \d+.?\d*

注意,后面使用 * 而不是 + ,是因为 + 表示至少有一位数字。加上前面的 \d+ ,表达式是需要匹配至少两位数。而 * 表示匹配前面字符 0 次、1 次或多次。

fda_str = '3号楼一单元1001,水费100.56'
fda_pat = r'\d+\.?\d*'
fda_r = re.findall(fda_pat, fda_str)
for i in fda_r:
    print(i)

输出结果:

3
1001
100.56

匹配正整数

写出匹配所有正整数的正则表达式。

^[1-9]\d*$

fda_lst = [11, 3, 1.3, 100.54, -5, 67]
fda_pat = r'^[1-9]\d*$'
re_lst = [i for i in fda_lst if re.match(fda_pat, str(i))]
print(re_lst)

输出结果:

[11, 3, 67]
re.I 忽略大小写

re.I 是方法的可选参数,表示忽略大小写。

re_str = 'This is the Way'
pat = r't'
r = re.finditer(pat, re_str, re.I)
for i in r:
    print(i.span())

输出结果:

(0, 1)
(8, 9)
split 分割单词

正则模块中 split 函数强大,能够处理复杂的字符串分割任务。

sp_str = 'This,;, is ; \t the || ,  Way  ;'
words_lst = re.split(r'[,\s;|]+', sp_str)
print(words_lst)

输出结果:

['This', 'is', 'the', 'Way', '']
sub 替换匹配串

替换匹配到的子串。

sub_str = 'This 2233 is station B 2233'
pat = re.compile(r'\d+')
mat = pat.sub("23333",sub_str)
print(mat)

输出结果:

This 23333 is station B 23333
compile 预编译

如果要用同一匹配模式,做很多次匹配,可以使用 compile 预先编译串。

案例:从一系列字符串中,挑选出所有正浮点数。

首先,生成预编译对象 rec:

rec = re.compile(r'^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$')

下面直接使用 rec,匹配列表中的每个元素,不用每次都预编译正则表达式,效率更高。

test_lst = [11, 'love', 3.33, -2.1, '666', 345, '2.33', 0.5]
res_lst = [i for i in test_lst if rec.match(str(i))]
print(res_lst)

输出结果:

[3.33, '2.33', 0.5]
贪心捕获

根据某个模式串,匹配到结果。

待爬取网页的部分内容如下所示,现在想要提取 <div> 标签中的内容。

content = '''<span>233333</span><div>bilibili</div><div>隐秘的角落</div>'''

通过正则提取 div 中的内容

result = re.findall(r'<div>.*</div>', content)
print(result)

输出结果:

['<div>bilibili</div><div>隐秘的角落</div>']

如果我们不想保留字符串最开始的 <div> 和结尾的 </div>,那么,就需要使用一对 () 去捕获。

result = re.findall(r'<div>(.*)</div>', content)
print(result)

输出结果:

['bilibili</div><div>隐秘的角落']
  • 结果中已经没有开始的 <div> ,结尾的 </div> 仅使用一对括号,便成功捕获到我们想要的部分。
  • (.*) 表示捕获任意多个字符,尽可能多地匹配字符,也被称为 贪心捕获
  • . 表示匹配除换行符外的任意字符。
非贪心捕获

上面的返回结果是: [‘bilibili</div><div>隐秘的角落’] ,对于剩下的 div 标签,我们也是不需要的,所以正则表达式还需要改进。

result = re.findall(r'<div>(.*?)</div>', content)

仅把上面的正则增加了一个 ? ,匹配串为: (.*?)

输出结果:

['bilibili', '隐秘的角落']

像这种匹配模式串,被称为非贪心捕获。

Python使用正则表达式非常方便,因为Python内置了一个名为`re`模块来支持这个功能。以下是关于如何在Python中运用正则表达式的简要介绍: ### 导入 re 模块 首先需要导入 `re` 库,这是操作所有与正则相关的函数的基础步骤。 ```python import re ``` ### 编译正则表达式 虽然可以直接将字符串作为参数传递给`re`库里的各个方法,但更推荐的方式是先创建一个Pattern对象(即编译后的正则表达式),然后再进行匹配或其他处理。这样做有助于提升效率,尤其是在多次使用相同的模式时。 ```python pattern = re.compile(r'\d+') # 匹配数字序列 ``` ### 进行搜索和替换 #### search() 和 match() - `match()` 函数只检查是否从头开始匹配成功; - 而 `search()` 则会在整个字符串里寻找第一个符合条件的位置。 两者返回的结果都是Match对象,如果没有找到匹配项,则返回None。 ```python result = pattern.search('example123string') if result: print("Found:", result.group()) else: print("No match") ``` #### sub() 替换文本内容 如果你想把某些部分替换成别的东西,可以用sub()来做。它接受三个参数:一个是旧的模式、二是新的值以及三是目标字符串。 ```python new_text = re.sub(r'\s+', ' ', text) # 将连续空白符改为单空格 print(new_text) ``` 此外还有其他一些常用的函数如 findall(), split() 等等可以根据实际需求选择合适的方法去解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值