1 模式串为什么需要原生字符串?
模式和待匹配字符串可以是Unicode字符串(str)或者8位字符串(bytes),但是模式和待匹配字符串必须是同一种类型。
当模式串为python str类型,正则表达式转义符号和python str的转义符号冲突。如果模式串需要表达反斜杠,正则表达式为 “\” ,而用python str来表达正则表达式 “\”,则需要两个python str形式的反斜杠(一个python str形式的反斜杠表示为 “\”),因此模式串的反斜杠用python str形式表达是 “\\”。
这种用python str来表示模式是不推荐(报DeprecreationWarning,以后可能报SyntaxError)
避免正则表达式的转义的和python str 字符串的转义之间的冲突,应当使用python原生字符串书写匹配模式,例如,正则表达式 “\” 使用python原生字符串可以表达为 r"\"。
2 在python中使用正则表达式
2.1 re.search()
- 函数签名:re.search(pattern, string, flags: _FlagsType = 0): -> re.Match
- 功能:扫描整个字符串,返回第一个匹配项
- 参数说明
参数名 | 说明 |
---|
pattern | 一般为原生字符串 |
string | 待匹配的文本 |
flag | 匹配行为的控制 |
import re
print(re.search('super','superstition').span())
print(re.search('super','insuperable').span())
2.2 re.match()
- 函数签名:re.match(pattern, string, flags: _FlagsType = 0) -> re.Match
- 功能:从字符串开头开始匹配,如果一开始不匹配就返回None
import re
print(re.match('super', 'superstition').span())
print(re.match('super','insuperable'))
2.3 re.findall()
- 函数签名:re.findall( pattern, string, flags: _FlagsType = 0) -> list[Any]
- 功能:扫描整个字符串,返回所有匹配的结果
import re
in_str = '''a\nabbabaabaa'''
print(re.findall(r'a.*?b', in_str))
print(re.findall(r'a.*?b', in_str, re.S))
2.4 re.sub()
- 函数签名:re.sub(pattern, repl, string, count=0, flag=0) -> str
- 功能:用repl替换string中的匹配项
- 参数说明
参数名 | 说明 |
---|
pattern | 匹配的模式,原生字符串 |
repl | 用于替换匹配出来的子串的字符串 |
string | 被匹配的字符串 |
count | 替换的最大次数,默认为0,所有匹配都被替换 |
import re
in_str = '''a\nabbabaabaa'''
ret_str = re.sub(r'a.*?b', 'XX', in_str, flags=re.S)
ret_str = re.sub(r'a.*?b', 'XX', in_str, 1, re.S)
ret_str = re.sub(r'a.*?b', 'XX', in_str, 2, re.S)
3 补充
3.1 match对象的方法
- group([group1, …]):返回被re匹配的字符串,group(0)返回全部匹配结果,group(n)返回第n个匹配结果
- start([group]):返回匹配开始的位置,group用于指定匹配的组
- end([group]):返回匹配结束的位置,group用于指定匹配的组
- span([group]):返回一个元组包含匹配(开始,结束)的位置,group用于指定匹配的组
3.2 flags取值表
修饰符 | 描述 |
---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.M | 多行匹配,影响 ^ 和 $ |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B. |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 |
3.3 正则表达式中关键字
关键字 | 说明 |
---|
. | 表示匹配除了/n的任意一个字符 |
* | 表示匹配前一个位置上的字符0次或者0次以上 |
? | 表示匹配前一个位置上的字符0次或者1次 |
^ | 匹配开始标志符 |
$ | 匹配结束标志符 |
{m} | 扩展前一个字符m次 |
{m,n} | 扩展前一个字符m到n次(含n) |
() | 分组标记,内部只能用 | 操作符。(abc)表示abc,(abc|def)表示abc或者def |
\d | 匹配一位数字,等价[0-9] |
\w | 匹配一个字符大小写字母或者数字字符,等价于[A-Za-z0-9] |
.* | 贪婪匹配,匹配边界字符之间的所有字符 |
.*? | 非贪婪匹配/最小匹配,匹配边界字符之间最少的字符 |
import re
print(re.findall(r'a.*?', 'aabbabaabbaa'))
result:['aab', 'ab', 'aab']
print(re.findall(r'a.*b', 'aabbabaabbaa'))
result:['aabbabaabb']
3.4 正则表达式例子
正则表达式 | 含义 |
---|
PY+ | P后有一个或无穷多个Y |
PY[^PY]{0,m} | 前缀为PY,后续不多于10个字符,且后续字符不能是P或者Y |
^[A-Za-z]+$ | 由大写或者小写英文字母组成的字符串 |
^[A-Za-z0-9]+$ | 由大写或者小写英文字或者数字母组成的字符串 |
^-?\d+$ | 整数形式(正整数或者负整数)字符串 |
^[0-9]*[1-9][0-9]*$ | 正整数形式(可以带有先导0)字符串 |
[1-9]\d{5} | 中国邮政编码,6位 |
[\u4e00-\u9fa5] | 中文字符 |
\d{3}-\d{8}|\d{4}-\d{7} | 国内电话号码,如010-98765432,0101-9876543 |