在语言中用正则处理文本处理
  4Txe79BjyroE 2023年11月02日 53 0

在进行文本处理时,正则解决的问题大概可以分成四类,分别是校验文本内容、提取文本内容、替换文本内容、切割文本内容。

1、校验文本内容

数据验证,通常我们在网页上输入的手机号、邮箱、日期等,都需要校验。校验的特点在于,整个文本的内容要符合正则,比如要求输入 6 位数字的时候,输入 123456abc 就是不符合要求的。

验证日期格式年月日为例子来讲解,比如 2020-01-01,我们使用正则\d{4}-\d{2}-\d{2} 来验证。

在 Python 中,正则的包名是 re,验证文本可以使用 re.match 或 re.search 的方法,这两个方法的区别在于,re.match 是从开头匹配的,re.search 是从文本中找子串。

# 测试环境 Python3
>>> import re
>>> re.match(r'\d{4}-\d{2}-\d{2}', '2020-06-01')
<re.Match object; span=(0, 10), match='2020-06-01'>
# 这个输出是匹配到了,范围是从下标0到下标10,匹配结果是2020-06-01
# re.search 输出结果也是类似的

在 Python 中,校验文本是否匹配的正确方式如下所示:

# 测试环境 Python3
>>> import re
>>> reg = re.compile(r'\A\d{4}-\d{2}-\d{2}\Z')  # 建议先编译,提高效率
>>> reg.search('2020-06-01') is not None
True
>>> reg.match('2020-06-01') is not None  # 使用match时\A可省略
True

2、 提取文本内容

所谓内容提取,就是从大段的文本中抽取出我们关心的内容。比较常见的例子是网页爬虫,或者说从页面上提取邮箱、抓取需要的内容等。

在 Python 中提取内容最简单的就是使用 re.findall 方法了,当有子组的时候,会返回子组的内容,没有子组时,返回整个正则匹配到的内容。下面我以查找日志的年月为例进行讲解,年月可以用正则 \d{4}-\d{2} 来表示:

# 没有子组时
>>> import re
>>> reg = re.compile(r'\d{4}-\d{2}')
>>> reg.findall('2020-05 2020-06')
['2020-05', '2020-06']

# 有子组时
>>> reg = re.compile(r'(\d{4})-(\d{2})')
>>> reg.findall('2020-05 2020-06')
[('2020', '05'), ('2020', '06')]

通过上面的示例你可以看到,直接使用 findall 方法时,它会把结果存储到一个列表(数组)中,一下返回所有匹配到的结果。如果想节约内存,可以采用迭代器的方式来处理,就像下面这样:

>>> import re
>>> reg = re.compile(r'(\d{4})-(\d{2})')
>>> for match in reg.finditer('2020-05 2020-06'):
...     print('date: ', match[0])  # 整个正则匹配到的内容
...     print('year: ', match[1])  # 第一个子组
...     print('month:', match[2])  # 第二个子组
...
date:  2020-05
year:  2020
month: 05
date:  2020-06
year:  2020
month: 06

3、替换文本内容

文本内容替换,替换通常用于对原来的文本内容进行一些调整。

在 Python 中替换相关的方法有 re.sub 和 re.subn,后者会返回替换的次数。下面以替换年月的格式为例进行讲解,假设原始的日期格式是月日年,要将其处理成 xxxx 年 xx 月 xx 日的格式。你可以看到,在 Python 中正则替换操作相关的方法,使用起来非常地简单。

>>> import re
>>> reg = re.compile(r'(\d{2})-(\d{2})-(\d{4})')

>>> reg.sub(r'\3年\1月\2日', '02-20-2020 05-21-2020')
'2020年02月20日 2020年05月21日'

# 可以在替换中使用 \g<数字>,如果分组多于10个时避免歧义
>>> reg.sub(r'\g<3>年\g<1>月\g<2>日', '02-20-2020 05-21-2020')
'2020年02月20日 2020年05月21日'

# 返回替换次数
>>> reg.subn(r'\3年\1月\2日', '02-20-2020 05-21-2020')
('2020年02月20日 2020年05月21日', 2)

4、切割文本内容

文本内容切割,通常切割用于变长的空白符号,多变的标点符号等。

在 Python 中切割相关的方法是 re.split。如果我们有按照任意空白符切割的需求,可以直接使用字符串的 split 方法,不传任何参数时就是按任意连续一到多个空白符切割。

# 使用字符串的切割方法
>>> "a b  c\n\nd\t\n \te".split()
['a', 'b', 'c', 'd', 'e']

使用正则进行切割,比如我们要通过标点符号切割,得到所有的单词(这里简单使用非单词组成字符来表示)

>>> import re
>>> reg = re.compile(r'\W+')
>>> reg.split("apple, pear! orange; tea")
['apple', 'pear', 'orange', 'tea']

# 限制切割次数,比如切一刀,变成两部分
>>> reg.split("apple, pear! orange; tea", 1)
['apple', 'pear! orange; tea']


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论