一、re库常用方法

re库常用函数

作用

re.findall(pattern, string)

根据pattern返回匹配结果(列表)

re.split(pattern, string)

使用pattern分割string,返回列表

re.sub(pattern, repl, string)

使用repl替换string中的pattern

1.1 re.findall(pattern, string)

找出文本中出现的年份

import re


pattern = '\d{4}'
string = """Python是一门面向对象的编程语言,诞生于1991年。\
目前以广泛应用在网站开发、游戏软件开发、数据采集、机器学习等多个领域。\
一般情况下Python是Java的20%,所以说人生苦短,我用Python。"""

re.findall(pattern, string)

Run

['1991']

1.2 re.split(pattern, string)

断句

pattern = '[。;]'

string = """Python是一门面向对象的编程语言,诞生于1991年;\
目前以广泛应用在网站开发、游戏软件开发、数据采集、机器学习等多个领域。\
一般情况下Python是Java的20%,所以说人生苦短,我用Python。"""

re.split(pattern, string)

Run

['Python是一门面向对象的编程语言,诞生于1991年',
 '目前以广泛应用在网站开发、游戏软件开发、数据采集、机器学习等多个领域',
 '一般情况下Python是Java的20%,所以说人生苦短,我用Python',
 '']

1.3 re.sub(pattern, repl, string)

将数字替换为NUM

pattern = '\d+'
repl = 'NUM'
string = """Python是一门面向对象的编程语言,诞生于1991年。\
一般情况下Python是Java的20%,所以说人生苦短,我用Python。"""

re.sub(pattern, repl, string)

Run

'Python是一门面向对象的编程语言,诞生于NUM年。一般情况下Python是Java的NUM%,所以说人生苦短,我用Python。'

从上面我们可以看到通过re库可以做很多精细巧妙的操作。re库并不难,难的是正则表达式的设计,下面带你认识一下正则表达式中的各种符号

二、正则表达式中的符号

按照符号的功能,我将其分为三类,一般情况下表达式都是由这三种符号组成的。

2.1 正则字符

正则符号

描述

匹配自己时

\

转义字符。例如, 'n' 匹配字符 'n'。

\\

( )

标记一个子表达式的开始和结束位置。

\( \)

.

匹配除换行符 \n 之外的任何单字符。

\.

|

|左右两侧均可参与匹配

\|

\d

匹配字符串中的单个数字

a-zA-Z

匹配全部英文字符

0-9

匹配全部数字

\s

匹配字符串中的\n,\t,空格

[]

中括号内任意正则符号均可参与匹配

\[ \]

^

当在方括号表达式中使用,^对其后的正则表达式进行了反义表达。

\^

2.2 限定字符

正则符号

描述

匹配自己时

*

匹配前面的子表达式零次或多次。

\*

?

匹配前面的子表达式零次或一次

\?

+

匹配前面的子表达式一次或多次。

\+

{m}

n 是一个非负整数。匹配确定的 m 次。

{m,}

m 是一个非负整数。至少匹配m 次。

{m, n}

m 和 n 均为非负整数,其中m <= n。最少匹配 m 次且最多匹配 n 次。

2.3 定位字符

正则符号

描述

匹配自己时

^

匹配输入字符串的开始位置。

\^

$

匹配输入字符串的结尾位置

\$

\b

匹配一个单词边界,即字与空格间的位置

\B

非单词边界匹配

感悟

正则符号和正则表达式晦涩难懂,即使上面的三类符号背的滚瓜烂熟,可能对解决问题暂时帮助不大。不如先放弃抵抗,我们再来看几个例子^_^幻想自己掌握了

三、案例

3.1 . 统一表达

将指代同一个主题的不同表达词语统一为同一个词

text = '中国铁路工程集团有限公司成立于1950年3月,总部位于北京。目前中国中铁已经发展成中国和亚洲最大的多功能综合型建设集团。'

pattern = '中国铁路工程集团有限公司|中国中铁'

repl = '中铁'
re.sub(pattern, repl, text)

Run

'中铁成立于1950年3月,总部位于北京。目前中铁已经发展成中国和亚洲最大的多功能综合型建设集团。'

3.2 分割文本数据的章节

text = """ 第一篇 Python简介 第二篇 Python入门语法 第三篇 Python网络爬虫 第四篇 文本数据编码 第五篇 数据分析 第六篇 可视化"""

pattern = '第[一二三四五六七八九十零百]+篇'

re.split(pattern, text)

Run

[' ',
 ' Python简介 ',
 ' Python入门语法 ',
 ' Python网络爬虫 ',
 ' 文本数据编码 ',
 ' 数据分析 ',
 ' 可视化']

3.3 抽取出数字

比如日期数据

text = '中国铁路工程集团有限公司成立于1950年3月,总部位于北京。目前中国中铁已经发展成中国和亚洲最大的多功能综合型建设集团。'

pattern = '(\d{4})年(\d{1,2})月'

re.findall(pattern, text)

Run

[('1950', '3')]

四、好东西留在最后

在你放弃治疗时,希望来了^_^

  • 搜索引擎检索到自己需要的正则表达式
  • 最简单最好用表达式(.*?)
  • 在正则表达式测试网站 http://c.runoob.com/front-end/854验证自己的正则表达式 

4.1 检索找到自己需要的正则表达式

比如我只需要中文,其余字符统统不要。

我会在百度搜中文正则表达式

发现很多网页中网友提到[\u4e00-\u9fa5]+,于是

import re


pattern = '[\u4e00-\u9fa5]+'

string = """Python是一门面向对象的编程语言,诞生于1991年。\
目前以广泛应用在网站开发、游戏软件开发、数据采集、机器学习等多个领域。\
一般情况下Python是Java的20%,所以说人生苦短,我用Python。"""

re.findall(pattern, string)

Run

['是一门面向对象的编程语言',
 '诞生于',
 '年',
 '目前以广泛应用在网站开发',
 '游戏软件开发',
 '数据采集',
 '机器学习等多个领域',
 '一般情况下',
 '是',
 '的',
 '所以说人生苦短',
 '我用']

4.2 最简单最好用表达式(.*?)

pattern设计步骤:

正则符号组成正则表达式,用于匹配需要的字符。

  1. 找到重复的一致的规律
  2. 复制粘贴到pattern中
  3. 扣掉想要的数据
  4. 替换为(.*?)  或者相应的正则符号表达式*

比如现在需要快速挖掘出intros中的姓名、籍贯和年龄

import re


pattern = '我叫(.*?),来自(.*?),今年(.*?)岁。'

intros = ['我叫张三,来自山东,今年25岁。',
          '我叫李四,来自河北,今年28岁。',
          '我叫王五,来自河南,今年24岁。']

for intro in intros:
    info = re.findall(pattern, intro)
    print(info)

Run

[('张三', '山东', '25')]
[('李四', '河北', '28')]
[('王五', '河南', '24')]

特别需要注意的是pattern中的(.*?)左右两侧必须有字符,否则匹配失败

import re


pattern = '(.*?),来自(.*?),今年(.*?)'

intros = ['我叫张三,来自山东,今年25岁。',
          '我叫李四,来自河北,今年28岁。',
          '我叫王五,来自河南,今年24岁。']

for intro in intros:
    info = re.findall(pattern, intro)
    print(info)

Run

[('我叫张三', '山东', '')]
[('我叫李四', '河北', '')]
[('我叫王五', '河南', '')]

由于

'(.*?),来自(.*?),今年(.*?)'

中最左侧和最右侧的(.*?)没有被其他字符左右包裹,导致匹配姓名和年龄失败。