正则表达式

正则表达式的作用

正则表达式(Regular Expression)是一种文本模式,包括普通字符(例如, a 到 z 之间的字母)和特殊字符(称为”元字符”)。

正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

正则表达式是繁琐的,但它是强大的,学会之后的应用会让你除了提高效率外,会给你带来绝对的成就感。只要认真阅读本教程,加上应用的时候进行一定的参考,掌握正则表达式不是问题。

许多程序设计语言都支持利用正则表达式进行字符串操作,在此我们以 python 的正则表达式模块为例。

正则表达式模块的简易使用

import re

print(re.search('regex', 'Example regex').group())

这样就是一个简单的全字匹配,其中 ‘regex’ 表示正则表达式, ‘Example regex’是目标字符串。

正则表达式规则

模式字符串使用特殊的语法来表示一个正则表达式:

字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。

多数字母和数字前加一个反斜杠时会拥有不同的含义。

标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

反斜杠本身需要使用反斜杠转义。

由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r’\t’,等价于 ‘\t’)匹配相应的特殊字符。

下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

字符 描述
^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配 ^ 字符本身,请使用 \^。
$ 匹配输入字符串的结尾位置。如果设置了 RegExp 对象的 Multiline 属性,则 $ 也匹配 ‘\n’ 或 ‘\r’。要匹配 $ 字符本身,请使用 \$。
( ) 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \( 和 \)。
* 匹配前面的子表达式零次或多次。要匹配 * 字符,请使用 \*。
+ 匹配前面的子表达式一次或多次。要匹配 + 字符,请使用 \+。
. 匹配除换行符 \n 之外的任何单字符。要匹配 . ,请使用 \. 。
[ 标记一个中括号表达式的开始。要匹配 [,请使用 \[。
? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配 ? 字符,请使用 \?。
\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如, ‘n’ 匹配字符 ‘n’。’\n’ 匹配换行符。序列 ‘\\’ 匹配 “\”,而 ‘\(‘ 则匹配 “(“。
{ 标记限定符表达式的开始。要匹配 {,请使用 \{。
| 指明两项之间的一个选择。要匹配 |,请使用 \|。

常用正则表达式示例

正则表达式在限制用户输入的时候起到很大的作用,比如用户名、密码等。

import re

example = ['电话: 12345678901', '邮箱1: [email protected]  邮箱2:[email protected]', '密码: abCD1234.', '用户名: 1abCD_',
           '身份证号: 12345678901234567X', 'ip地址: 1.23.456.789', '个人主页; example.com.cn']
# 电话
print(re.search('\d{11}', example[0]).group())
# 12345678901

# 邮箱
print([each.group() for each in re.finditer('[a-zA-Z0-9][email protected]([a-zA-Z0-9]+\.){1,2}[a-z]+', example[1])])
# ['[email protected]', '[email protected]']

# 密码(大小写字母 数字 小数点 5位以上)
print(re.search('[a-zA-Z0-9.]{5,}', example[2]).group())
# abCD1234.

# 用户名(大小写字母 数字 下划线 5位以上)
print(re.search('[a-zA-Z0-9_]{5,}', example[3]).group())
# 1abCD_

# 身份证号
print(re.search('\d{17}[\dxX]', example[4]).group())
# 12345678901234567X

# ip地址
print(re.search('(\d{1,3}\.){3}(\d{1,3})', example[5]).group())
# 1.23.456.789

# 网址
print(re.search('([a-zA-Z0-9]+\.)+[a-zA-Z]+', example[6]).group())
# example.com.cn

python的正则表达式一共有4种匹配模式:

re.match(regex, content)

从字符串开头开始匹配,也就是说,如果字符串第一个字母就不匹配,则返回None,即匹配失败。

regex = 'regex'
example = 'example regex'
print(re.match(regex, example))
# None

因为’regex’这个单词并不能匹配字符串开头的’example’单词。

re.search(regex, content)

最常用的单次匹配,这个函数只会返回第一次命中的字符串的相关信息,后边的字符串都会被忽略。

regex = '\d'
example = '123'
print(re.search(regex, example).group())
# 1

re.findall(regex, content)

这个函数是用来匹配所有的组,并返回一个list。
那么,什么是组?
(正则表达式中,如果没有括号,结果就是整个正则表达式匹配命中的字符串;如果有括号的,则使是括号中匹配成功的内容;多个括号的,每个list元素就会变成一个tuple)

# test 1
regex = '\d([a-z])'
example = '1a2b3c'
print(re.findall(regex, example))
# ['a', 'b', 'c']

# test 2
regex = '\d[a-z]'
example = '1a2b3c'
print(re.findall(regex, example))
# ['1a', '2b', '3c']

# test 3
regex = '\d([a-z])(\d)'
example = '1a2b3c4d'
print(re.findall(regex, example))
# [('a', '2'), ('c', '4')]

re.finditer(regex, content)

这个函数返回所有成功的匹配结果,取字符串时和re.search()一样,也要调用group()函数。

regex = '\d([a-z])'
example = '1a2b3c'
print([each for each in re.finditer(regex, example)])
# [<_sre.SRE_Match object; span=(0, 2), match='1a'>, <_sre.SRE_Match object; span=(2, 4), match='2b'>, <_sre.SRE_Match object; span=(4, 6), match='3c'>]
print([each.group() for each in re.finditer(regex, example)])
# ['1a', '2b', '3c']

发表评论

电子邮件地址不会被公开。 必填项已用*标注