工作学习中常用的【正则表达式】总结。文末分享好用的工具和案例总结。
正则表达式,是一种特殊的字符序列,能帮助我们去检查字符串是否与某种模式相匹配。
1、基本元字符含义
2、常用正则函数
3、正则表达式结合Pandas示例
4、常用正则表达式工具
文章转载自:公众号 语言技术
原文链接:正则表达式基础语法、函数和工具总结(Python示例)
关于正则表达式的基础语法和字符释义讲解。不懂的时候翻阅一下就可以,不用死记硬背。
01 常用元字符
元字符有. [ ] () ^ $ | \ ? * + { }共11种
02 常用量化符
量化符
也叫重复修饰符,将紧挨着量化符前面的那个字符,匹配0次、1次或者多次。
在 *?, +?, ??中,'*', '+',和 '?' 修饰符都是 *贪婪的,*在字符串进行尽可能多的匹配。
在修饰符之后添加 ? 将使样式以非贪婪方式或者最小方式进行匹配;尽量 少的字符将会被匹配。
常用模块
03 常用模块
re.A (只匹配ASCII字符), re.I (忽略大小写),
re.L (语言依赖), re.M (多行模式), re.X (冗长模式),
re.S (点dot匹配全部字符), re.U (Unicode匹配)
04 其他常用符号示意
[] 字符集合
字符可以单独列出,
比如 [amk]匹配'a''m'或者'k'。
将正则表达式的样式编译为一个正则表达式对象(正则对象),通过这个对象的方法 match、search() 等做匹配。
这个表达式的行为可以通过指定标记的值来改变。值可以是任意变量,可以通过位的OR操作( | 操作符)来结合。
prog = re.compile(pattern)
result = prog.match(string)
等价于
result = re.match(pattern, string)
# 匹配字符集abc与字符串匹配的第一个字符。
prog = re.compile('[abc]')
print(prog.search('abcd').group()) # a
如果需要多次使用这个正则表达式的话,使用 re.compile() 和保存这个正则对象以便复用,可以让程序更加高效。
通过 re.compile() 编译后的样式和模块级的函数会被缓存, 所以少数的正则表达式使用无需考虑编译的问题。
扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的匹配对象。如果没有匹配,就返回一个 None。这和找到一个零长度匹配是不同的。
# \w 用来匹配单次字符 包括a-z A-Z 0-9 _
r = re.search('a\w+', 'how are you')
# 获取匹配到的结果
print(r.group()) # are
如果 string 开始的0或多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。
即便是MULTILINE多行模式, re.match()也只匹配字符串的开始位置,而不匹配每行开始。如果你想定位 string 的任何位置,使用 search()来替代。
# \w 用来匹配单次字符 包括a-z A-Z 0-9_
r = re.match('h\w+', 'how are you')
# 获取匹配到的结果
print(r.group()) # how
如果整个 string 匹配到正则表达式样式,就返回一个相应的匹配对象 。否则就返回一个 None ;注意这跟零长度匹配是不同的。
用 pattern 分开 string 。如果在 pattern中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。
# 按照 “;"或者",” 对字符串进行分割
re.split('[;,]', 'abc,qwer; opq, mn')
# ['abc', 'qwer', ' opq', ' mn']
>>> re.split(r'\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split(r'(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split(r'\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']
如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也是一样:
>>> re.split(r'(\W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']
这样的话,分隔组将会出现在结果列表中同样的位置。样式的空匹配仅在与前一个空匹配不相邻时才会拆分字符串。>>> re.split(r'\b', 'Words, words, words.')['', 'Words', ', ', 'words', ', ', 'words', '.']
>>> re.split(r'\W*', '...words...')
['', '', 'w', 'o', 'r', 'd', 's', '', '']
>>> re.split(r'(\W*)', '...words...')
['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']
返回 pattern 在 string 中的所有非重叠匹配,以字符串列表或字符串元组列表的形式。对 string 的扫描从左至右,匹配结果按照找到的顺序返回。
空匹配也包括在结果中。返回结果取决于模式中捕获组的数量。
如果没有组,返回与整个模式匹配的字符串列表。
如果有且仅有一个组,返回与该组匹配的字符串列表。
如果有多个组,返回与这些组匹配的字符串元组列表。非捕获组不影响结果。
# 匹配包含所有带有o的单词
re.findall('\wo\w+', 'how are you')
# ['how', 'you']
re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
# ['foot', 'fell', 'fastest']
re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
# [('width', '20'), ('height', '10')]
在 string 里所有的非重复匹配,返回为一个迭代器 iterator 保存了匹配对象 。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。
返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。
如果样式没有找到,则不加改变地返回 string。
repl 可以是字符串或函数;如为字符串,则其中任何反斜杠转义序列都会被处理。
如果repl是一个函数,那它会对每个非重复的 pattern 的情况调用。这个函数只能有一个匹配对象参数,并返回一个替换后的字符串。
可选参数 count 是要替换的最大次数;count 必须是非负整数。如果省略这个参数或设为 0,所有的匹配都会被替换。
def dashrepl(matchobj):
... if matchobj.group(0) == '-': return ' '
... else: return '-'
>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')'pro--gram files'
>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
'Baked Beans & Spam'
转义 pattern 中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的。
>>> print(re.escape('https://www.python.org'))
https://www\.python\.org
>>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"
>>> print('[%s]+' % re.escape(legal_chars))
[abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+
>>> operators = ['+', '-', '*', '/', '**']
>>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))
/|\-|\+|\*\*|\*
函数对比
工作中我们常常使用pandas读取和操作数据,那么如何结合正则表达式去处理数据呢?
结合自定义函数
# 取出 #后的内容,并去除井号
df = pd.DataFrame({
'sentence': ['#Obama says goodbye', 'Just a simple #egg']})
# 将功能实现,封装成一个方法
def find(text):
h = re.findall(r'*#(\w+)',text)
return ''.join(h)
# pandas 结合 apply和lambda函数处理某列内容
df['new'] = df.sentence.apply(lambda x:find(x))
数据清洗
结合re.sub函数可以做数据清洗,替换掉文本中不要的字符。
df['sentence']=df['sentence'].astype('str').apply(lambda x: re.sub('[0-9+,,.。…、“”^_?::’‘''""()();;【】!!*?]+', '', x))
分享几个私藏好用的正则表达式网站工具,可视化正则表达式和学习教程。
https://github.com/CJex/regulex
https://devtoolcafe.com/tools/regex#!flags=img&re=
https://github.com/Bowen7/regex-vis
https://ihateregex.io/
https://github.com/geongeorge/i-hate-regex
https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md
https://regexlearn.com/zh-cn
https://github.com/aykutkardas/regexlearn.com
本文参考:
https://docs.python.org/zh-cn/3/library/re.html#module-contents