美文网首页
Python碎碎念(2):正则表达式

Python碎碎念(2):正则表达式

作者: xxlee | 来源:发表于2019-03-06 15:18 被阅读0次

转载请在文章起始处注明出处,谢谢。

文章转自本人之前博客

0. 写在前面

正则表达式,是一种强大的匹配模式。

1. 使用正则表达式的步骤

a.用import re导入正则表达式模块;

b.用re.compile()函数创建一个Regex对象(记得使用原始字符串r);

c.向Regex对象的search()方法传入想查找的字符串,它返回一个Match()对象;

d.调用Match()对象的group()方法,返回实际匹配文本的字符串。

例如:

import re 

phoneNumRegex = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')

mo = phoneNumRegex.search('My number is 123-456-7890.')  #mo是一个通用名称,用于Match对象。

print('Phone number found:' + mo.group())

注意:除了search()方法外,还有findall()方法。search()返回一个Match()对象,而findall()返回一组字符串列表,包含被查找字符串中所有匹配。若正则表达式中有分组,则返回一个元组的列表。

2. 正则表达式匹配更多模式

2.1利用括号进行分组

添加括号可以在正则表达式中创建“分组”,使用group()匹配对象的方法,从分组中获得匹配文本。

例如:

(\d\d\d)-(\d\d\d-\d\d\d\d)  如:123-456-7890

group(1) ----> '123'
group(2) ----> '456-7890'
group(0)或group() ----> '123-456-7890'
groups() ---->  ('123','456-7890')   #可以使用多重赋值的方法

2.2用管道匹配多个分组

字符’|’被称为管道,用来匹配许多表达式中的一个。

2.3问号实现可选匹配

‘?’匹配之前分组零次或一次。

2.4星号匹配零次或多次

‘*’匹配之前的分组零次或多次。

2.5加号匹配一次或多次

‘+’匹配之前的分组一次或多次

2.6花括号匹配特定的次数

例如:

(ha){3} ----> 'hahaha'

(ha){3,5} ---->  'hahaha'、'hahahaha'、'hahahahaha'  

(ha){3,5}相当于管道匹配((hahaha)|(hahahaha)|(hahahahaha))

3. 贪心和非贪心匹配

Python正则表达式默认“贪心”匹配,即匹配最长的字符串。

花括号的“非贪心”匹配,匹配最短的字符串,要在结束的花括号后跟一个问号。

例如:

(ha){3,5}  #贪心匹配

(ha){3,5}?  #非贪心匹配

4. 字符分类

\d 0~9的任意数字

\D 除0~9的数字以外任何字符

\w 任何字母、数字、下划线字符(可以认为是匹配“单词”字符)

\W 除字母、数字、下划线字符以外的任何字符

\s 空格、制表符、换行符(可以认为是匹配“空白”字符)

\S 除空格、制表符、换行符以外的任何字符

例如:

[0-5] ----> 0~5

\d+\s\w+ ----> 12 words

5. 建立自己的字符分类

使用方括号[]定义自己的字符分类。

例如:

[aeiouAEIOU]匹配所有元音字符,不论大小。

注意:方括号内的普通正则表达式符号不会被解释,也就是说不需要加\。

在字符分类的左括号后加^,表示非字符类。

例如:

[^aeiouAEIOU]表示匹配所有的非元音字符。

6. 插入字符(^)和美元字符($)

在正则表达式开始处使用插入字符(^),表明匹配必须发生在被查找文本开始处。

在正则表达式末尾处加上美元字符($),表明字符串必须以这个正则表达式的模式结束。

例如:

正则表达式r'^\d+$'表明开始和末尾都是数字。

7. 通配字符

正则表达式中句点(.)被称为通配字符,匹配除换行之外的所有单个字符。

注意:句点字符只匹配一个字符。

7.1 点星匹配所有字符

.* 表示任意文本,使用的是贪心匹配,若想使用非贪心匹配,则需要在后面加?,即.*?。

7.2 句点字符匹配换行

.* 匹配所有除换行外的字符,通过传入re.DOTALL作为re.compile()的第二个参数,可以让句点字符匹配所有字符,包括换行符。

8. 不区分大小写的匹配

要让正则表达式不区分大小写,可以向re.compile()中传入re.IGNORECASE或re.I,作为第二个参数。

9. 用sub()方法替换字符串

Rxgex对象的sub()方法,传入两个参数,第一个参数是一个字符串,用来取代发现的匹配;第二个参数是正则表达式。sub()方法返回替换完成的字符串。

例如:

namesRegex = re.compile(r'Agent \w+')

namesRegex.sub('CENSORED','Agent Alice gave the secret documents to Aengt Bob.')

有时候,可能需要使用匹配文本本身,作为替换的一部分,在sub()的第一个参数中输入\1\2\3..,表示在替换中输入分组1、2、3..的文本。

例如:

import re
agentnameRegex = re.compile(r'Agent (\w)\w*')
print(agentnameRegex.sub(r'\1@@','Agent a told Agent b that Agent c knew Agent d was a double agent.'))

输出:

a@@ told b@@ that/ c@@ knew d@@ was a double agent.

10. 管理复杂的正则表达式

若正则表达式比较长、复杂,想忽略正则表达式中的空白符和注释,可以使用re.VERBOSE,作为第二个参数。

例如:

import re

phoneRegex = re.compile(r'''(
    (\d{3}|\(\d{3}\))?    #area code
    (\s|-|\.)?             #separator
    \d{3}                 #first 3 digits
    (\s|-|\.)             #separator
    \d{4}                 #last 4 digits
    (\s*(ext|x|ext.)\s*\d{2,5})? #extension
    )''', re.VERBOSE)

print(phoneRegex.findall('(123) 456-7890 ext. 123  123-456-7890'))

输出:

[('(123) 456-7890 ext. 123', '(123)', ' ', '-', ' ext. 123', 'ext.'), ('123-456-7890', '123', '-', '-', '', '')]

11. 项目:电话号码和Email地址提取程序

假设有一个无聊的任务,需要在一篇长的网页或者文章中,找出所有电话号码和邮件的地址。如果手动翻页,可能需要查找很长时间,如果有一个程序,可以在剪贴板的文本中查找电话号码和Email地址,那就只需要按一下Ctrl-A选择所有文本,按下Ctrl-C将它复制到剪贴板,然后运行程序。就可以自动找到电话号码和Email地址,替换掉剪贴板中的文本。

import re,pyperclip

#为电话号码创建一个正则表达式

phoneRegex = re.compile(r'''(
    (\d{3,4}|\(\d{3,4}\))?    #area code or telphone number
    (\s|-|\.)?             #separator
    (\d{8})                 #8 digits
    (\s*(ext|x|ext.)\s*\d{2,5})? #extension
    )''', re.VERBOSE)

#为Email创建一个正则表达式

emailRegex = re.compile(r'''(
    [a-zA-Z0-9._%+-]+    #username
    @                    
    [a-zA-Z0-9.-]+       #domain name
    (\.[a-zA-Z]{2,4})    #dot-something
    )''',re.VERBOSE)

#在剪贴板文本中找到所有匹配

text = str(pyperclip.paste())

matches = []

for groups in phoneRegex.findall(text):
    phoneNum = ' '.join([groups[1],groups[3]])
    if groups[4] != '':
        phoneNum += '-' + groups[4]
    matches.append(phoneNum)

for groups in emailRegex.findall(text):
    matches.append(groups[0])

#将所有匹配连接成一个字符串,复制到剪贴板

if len(matches) > 0:
    pyperclip.copy('\n'.join(matches))
    print('Copied to clipboard:')
    print('\n'.join(matches))
else:
    print('No phone numbers or email address found.')

相关文章

  • Python碎碎念(2):正则表达式

    转载请在文章起始处注明出处,谢谢。 文章转自本人之前博客 0. 写在前面 正则表达式,是一种强大的匹配模式。 1....

  • 改观

    我很少写碎碎念,但喜欢看别人的碎碎念。 最近几天阅读,发现碎碎念的文章少了。 讲真,碎碎念,发泄居多,正能量少。 ...

  • Python碎碎念

    花了一天半写完了第一个作业。 不叫它大作业是因为它只有10分。 可是花了我一天半,也算是个大作业的量了QAQ。 有...

  • 2018-10-18

    碎碎念 碎碎念 很烦碎碎念 生活的确是琐碎,可我很讨厌碎碎念。 爸爸是个很软弱的人,生活只是基本自理,并不追求...

  • IISC2020-线下赛re

    碎碎念 帮忙做了一个re题,题目挺简单的,是python 的exe解包,做了还是写写吧hhh python exe...

  • 发现日常工作碎碎念

    碎碎念害人,紫雨老师手帐课里面曾经就碎碎念单独有专门的一节课,而且我的碎碎念也是很多,这些不经意的碎碎念就会让我们...

  • 自己做的不够多、好【成交不确定选对2】

    【碎碎念1:觉得自己推广做的不够多,好。文章写得不够多,很多内容都没有及时听、及时反思。】 【碎碎念2:没有去更多...

  • 08主题碎碎念追踪:如何发现高频发的碎碎念和场景剧情?课后感

    这节课老师讲的是记录主题式的碎碎念的方法。 主题式的碎碎念:就是从日常碎碎念中把主题式碎碎念给抽离出来。 自己最长...

  • 【读书清单】《人性的弱点》夫妻相处10大妙招

    文|萌 001切勿喋喋不休 可能碎碎念是所有人都不喜欢的,既不喜欢父母碎碎念,也不喜欢朋友碎碎念,更不喜欢伴侣碎碎...

  • 一条狗

    碎碎念

网友评论

      本文标题:Python碎碎念(2):正则表达式

      本文链接:https://www.haomeiwen.com/subject/nlztpqtx.html