匹配(试图在字符串的开始位置进行匹配) 搜索(试图从字符串的任何位置开始匹配)
正则表达式中的特殊符号和字符,即所谓的元字符,给予了正则表达式强大的功能和灵活性
常见正则表达式符号和特殊字符
表 示 法 | 描 述 | 正则表达式示例 |
符号 | ||
literal | 匹配文本字符串的字面值 literal | foo |
re1|re2 | 匹配正则表达式 re1 或者 re2 | foo|bar |
. | 匹配任何字符(除了\n 之外) | b.b |
^ | 匹配字符串起始部分 | ^Dear |
$ | 匹配字符串终止部分 | /bin/*sh$ |
* | 匹配 0 次或者多次前面出现的正则表达式 | [A-Za-z0-9]* |
+ | 匹配 1 次或者多次前面出现的正则表达式 | [a-z]+\.com |
? | 匹配 0 次或者 1 次前面出现的正则表达式 | goo? |
{N} | 匹配 N 次前面出现的正则表达式 | [0-9]{3} |
{M,N} | 匹配 M~N 次前面出现的正则表达式 | [0-9]{5,9} |
[…] | 匹配来自字符集的任意单一字符 | [aeiou] |
[..x-y..] | 匹配 x~y 范围中的任意单一字符 | [0-9], [A-Za-z] |
[^…] | 不匹配此字符集中出现的任何一个字符,包括某一范围的字符(如果在此字符集中出现) | [^aeiou], [^A-Za-z0-9] |
(*|+|?|{})? | 用于匹配上面频繁出现/重复出现符号的非贪婪版本(*、 +、 ?、 {}) | .*?[a-z] |
(…) | 匹配封闭的正则表达式,然后另存为子组 | ([0-9]{3})?,f(oo|u)bar |
表 示 法 | 描 述 | 正则表达式示例 |
特殊字符 | ||
\d | 匹配任何十进制数字,与[0-9]一致(\D 与\d 相反,不匹配任何非数值型的数字) | data\d+.txt |
\w | 匹配任何字母数字字符,与[A-Za-z0-9_]相同(\W 与之相反) | [A-Za-z_]\w+ |
\s | 匹配任何空格字符,与[\n\t\r\v\f]相同(\S 与之相反) | of\sthe |
\b | 匹配任何单词边界(\B 与之相反) | \bThe\b |
\N | 匹配已保存的子组 N(参见上面的(…)) | price: \16 |
\c | 逐字匹配任何特殊字符 c(即,仅按照字面意义匹配,不匹配特殊含义) | \., \\, \* |
\A(\Z) | 匹配字符串的起始(结束)(另见上面介绍的^和$) | \ADear |
扩展表示法 | ||
(?iLmsux) | 在正则表达式中嵌入一个或者多个特殊“标记” 参数(或者通过函数/方法) | (?x),(? im) |
(?:…) | 表示一个匹配不用保存的分组 | (?:\w+\.)* |
(?P<name>…) | 像一个仅由 name 标识而不是数字 ID 标识的正则分组匹配 | (?P<data>) |
(?P=name) | 在同一字符串中匹配由(?P<name)分组的之前文本 | (?P=data) |
(?#…) | 表示注释,所有内容都被忽略 | (?#comment) |
(?=…) | 匹配条件是如果…出现在之后的位置,而不使用输入字符串;称作正向前视断言 | (?=.com) |
(?!…) | 匹配条件是如果…不出现在之后的位置,而不使用输入字符串;称作负向前视断言 | (?!.net) |
(?<=…) | 匹配条件是如果…出现在之前的位置,而不使用输入字符串;称作正向后视断言 | (?<=800-) |
(?<!…) | 匹配条件是如果…不出现在之前的位置,而不使用输入字符串;称作负向后视断言 | (?<!192\.168\.) |
(?(id/name)Y|N ) | 如果分组所提供的 id 或者 name(名称)存在,就返回正则表达式的条件匹配 Y,如 果不存在,就返回 N; |N 是可选项 |
(?(1)y|x) |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
group方法,可以用来定位我要查找文本中的文本(findall的返回结果是列表,而列表是没有group方法的)
如果正则表达式pattern里面有(),表示对数据的分组,括号可以有多个,一个括号一组,按顺序从1开始(注意不是0是1),可以对结果使用.(group(num=0)方法索取,可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。没有分组的话使用.group()会报错.
.group(0)是打印搜索的结果
.group()返回str类型
想在某个组中不区分大小写请在组中开头加上(?i:)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
re.findall()返回一个列表(无论匹配不匹配)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
re.search 扫描整个字符串并返回第一个成功的匹配。
函数语法:
re.search(pattern, string, flags=0)
匹配成功re.search方法返回一个匹配的对象(类型是_sre.SRE_Match),否则返回None.
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
re.split(pattern, string, max=0)
将string以pattern为界分解成多个段,按顺序存入列表
为什么out第一个是''呢
In[28]: b = re.split(r"a","abajajodfnadd") In[29]: b Out[29]: ['', 'b', 'j', 'jodfn', 'dd']
列表中第一个元素的意思是a把字符串分割成[0:0]的范围,显然这个范围是没有任何数据的,验证如下
In[32]: c = 'abcsdfs' In[33]: c[0:1] Out[33]: 'a' In[34]: c[0:0] Out[34]: ''
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
"(\d){3}" 这个表达式是要匹配连续的三个数字,但是这个表达式中只有一个小括号,表明只有一个组,每个组中只会有一个数字
"(\d{3})"而这样写是一个组中有三个数字!
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
贪婪与费贪婪
data = 'Thu Feb 15 17:46:04 2007::[email protected]::1171590364-6-8' patt = '.+(\d+-\d+-\d+)' re.search(patt, data).group(1)(patt, data).group(1)
这里我们本来是想匹配1171590364-6-8的,但是结果却是4-6-8,这是由于正则表达式中的'.+'是贪婪的,匹配了'Thu Feb 15 17:46:04 2007::[email protected]::117159036'
,他比(\d+-\d+-\d+)靠前,会尽量匹配最大长度的字符串,但是他不能贪婪的把所有值都匹配上,所以他留给了(\d+-\d+-\d+)一个尽可能小的匹配长度(4-6-8)
想要消除'.+'的贪婪在他后面加上?即可
patt = '.+?(\d+-\d+-\d+)'