正则的学习

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则的学习相关的知识,希望对你有一定的参考价值。

正则表达式
正则表达式定义
正则表达式(regular expression)是一个特殊的字符序列,描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串。将匹配的子串替换或者从某个串中取出符合某个条件的子串,或者是在指定的文章中抓取特定的字符串等

正则表达式大致的匹配过程是:
拿正则表达式依次和字符串或者文本中的字符串做比较,如果每一个字符都匹配,则匹配成功,只要有一个匹配不成功的字符,则匹配不成功。

正则表达式的原始字符表示r
由于正则表达式通常会包含反斜杠等特殊字符,所以最好用原始字符串来表示,例如:
r”d” 等价于\d 表示匹配一个数字

正则表达式的原始字符表示r
由于正则表达式通常会包含反斜杠等特殊字符,所以最好用原始字符串来表示,例如:
r”d” 等价于\d 表示匹配一个数字

正则表达式的贪婪性
正则表达式中数量词(* 、+、?、{m,n})默认是贪婪的,会尽量多的去匹配满足条件的字符;
字符转abbbc,如果用ab* ,会匹配abbb

>>> re.match(r"ab*","abbbc").group()
‘abbb‘

抑制正则表达式的贪婪性
虽然正则表达式中数量词默认是贪婪的,但是可以在数量词的后面加上?来抑制贪婪性,表示匹配尽可能少的满足条件的字符

>>> re.match(r"ab*?","abbbc").group()
‘a‘
>>> re.search(r"d+?$","a123456").group()#$前的?不能屏蔽贪婪模式
‘123456‘

在使用?抑制贪婪性时候,?后面不能有字符存在,否则抑制失效

一个抑制贪婪的例子
>>> patt = r".+(d+-d+-d+)"
>>> m = re.match(patt,data)
>>> m.group()
‘Sat Apr 28 06:55:01 1973::[email protected]::104799301-4-12‘
>>> m.group(1)
‘1-4-12‘
我们想要用分组提取104799301-4-12,而不是1-4-12‘,第一个整数的其余部分在哪里?
问题在于正则表达式本质上是贪婪匹配。这意味着对于该统配符模式,将对正则表达式从左至右按顺序求值,而且试图匹配该模式的尽可能多的字符;使用.+将获取从字符串起始位置开始的全部单个字符,包括我们所期望提取的第一个整数部分,而d+仅仅需要一个数字,因此匹配到4,.+匹配了从字符串起始部分到所期望的第一个数字的全部内容10479930

我们可以使用非贪婪操作符?抑制贪婪匹配,在.+后加?后,获得了我们所期望的‘104799301-4-12‘

>>> patt = r".+?(d+-d+-d+)"
>>> m = re.match(patt,data)
>>> m.group()
‘Sat Apr 28 06:55:01 1973::[email protected]::104799301-4-12‘
>>> m.group(1)
‘104799301-4-12‘

其实我们也可以使用::作为字符分割符
>>> patt = r".+::(d+-d+-d+)"
>>> re.match(patt,data).group(1)
‘104799301-4-12‘

正则表达式元素
.(点)  匹配除换行符外的任意一个字符,但是在re.DOTALL模式中可以匹配换行符

     转义一个特殊的字符,使这个字符表示字面上本来的意思,比如:.表示匹配一个点,$匹配$符号
d  匹配任意一个数字,等价于[0-9]
D  匹配任意一个非数字,等价于[^0-9]
s  匹配任意一个空白字符,包括 空格、	 
 
 v f
S  匹配任意一个非空白字符,等价于[^s]
w  匹配一个字母或数字或下划线_,等价于[A-Za-z0-9_]
W  匹配一个非字母或非数字或非下划线,等价于[^A-Za-z0-9_]
[...]  匹配其中的任意一个字符
[^...]  不匹配方括号中出现的单个字符

正则表达式数量词
* 匹配前一个字符0次或多次
+ 匹配前一个字符1次或多次
?匹配前一个字符0次或1次
{n} 匹配前一个字符n次
{m,n} 匹配前一个字符m 到n次
{m,}  匹配前一个字符至少m次
{,n}  匹配前一个字符最多n次

正则表达式特殊表达式
^ 匹配字符串的开头,如果用在方括号中,表示否定,如:[^0-9]非数字字符
& 匹配字符串的结尾
 匹配单词的边界,也就是单词和空格间的位置,例如, ‘er‘ 可以匹配"never" 中的 ‘er‘,但不能匹配 "verb" 中的 ‘er‘。其实也可以匹配逗号、句号等其他字符和单词之间的位置,但是不能匹配数字和单词之间的位置
|  或匹配符,表达左右正则表达式任意匹配一个。如果左边的表达式匹配上了,匹配结束,不再匹配右边的表达式。该符号一般放在()中使用,如果没在圆括号中则它的范围是整个正则表达式。
<number>  引用分组匹配到的分组编号为<number>的字符串
(?P<name>...) 命名分组,给分组指定一个别名,P是大写
(?P=name)  引用分组名为name的分组匹配,这个是在正则表达式中引用,表示匹配重复的字符串,也可以使用编号引用
(?<=Pattern)  前向肯定断言语法,匹配的字符串前面存在Pattern匹配的内容才可以匹配成功,是输出匹配的字符串,Pattern匹配的内容不输出
            如: re.search(r"(?<=d{3})[A-Z]+","12A345B"),大写字母前面有3个数字才可以匹配大写字母,此处匹配B,且输出B
            注意前向肯定、前向否定量词只能使用{n} 不能使用+ 、*等
(?<!Pattern)  前向否定断言语法,匹配的字符串前面不存在Pattern匹配的内容才可以匹配成功,是输出匹配的字符串,Pattern匹配的内容不输出
            如: re.search(r"(?<!d{3})[A-Z]+","12A345B"),大写字母前面不是3个数字才可以匹配大写字母,此处匹配A,且输出A
(?=Pattern)  后向肯定断言语法,匹配的字符串后面存在Pattern匹配的内容才可以匹配成功,是输出匹配的字符串,Pattern匹配的内容不输出
           如:后面有多个小写字母的数字才会匹配
           >>> re.search(r"d+(?=[a-z]+)","1 23ab4").group()
‘23‘
(?!Pattern)  后向否定断言语法,匹配的字符串后面不存在Pattern匹配的内容才可以匹配成功,是输出匹配的字符串,Pattern匹配的内容不输出
          如:后面不是多个小写字母的数字才会匹配
          >>> re.search(r"d+(?![a-z]+)","1 23ab4").group()
‘1‘
(?#...)  后面的内容被当做注释忽略

(?iLmsux)
(集合‘i‘,?‘L‘,?‘m‘,?‘s‘,?‘u‘,?‘x‘中的一个或多个字母。)这个分组空字符串;这些字母整个正则表达式设置相应的标记:re.I(忽略大小写),re.L(依赖区域设置),re.M(多行),re.S(点号匹配所有字符),re.U(依赖Unicode),re.X(详细模式)。(这些标志在模块的内容中讲述)。它用于如果你想要包含这些标志作为正则表达式的一部分,而不是将flag参数传递给re.compile()函数。
请注意,(?x)标志更改解析表达的方式。它应使用在表达式字符串的开始,或一个或多个空白字符之后。如果在这个标志之前有非空白字符,结果是未定义的。

(?:...)
括号形式的正则表达式的非匹配版本。匹配括号中的任何正则表达式,但是匹配的子字符串不能在匹配后提取或在模式中引用。

(?iLmsux) 
>>> re.match(r"(?i)[a-z]+","ABC")
<_sre.SRE_Match object; span=(0, 3), match=‘ABC‘>
>>> re.match(r"(?i)[a-z]+","ABC").group()
‘ABC‘
等价于
>>> re.match(r"[a-z]+","ABC",re.I).group()
‘ABC‘

正则表达式编译模式的使用步骤:
1、编译正则表达式,输出正则表达式对象
2、使用正则表达式对象处理文本并输出正则匹配对象

>>> pattern = re.compile(r"d+")#编译正则表达式
>>> type(pattern)
<class ‘_sre.SRE_Pattern‘>#正则表达式对象
>>> pattern.search("a123b")
<_sre.SRE_Match object; span=(1, 4), match=‘123‘>#正则匹配对象
>>> pattern.search("a123b").group()#正则匹配对象调用group()输出匹配内容
‘123‘

re.compile 函数
compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。

语法:
re.compile(pattern[, flags])
pattern 字符串形式的正则表达式
flags 可选,表示匹配模式
   re.I 忽略大写写
   re.L 表示特殊字符集,w, W, , B, s, S 依赖当前环境
   re.M 多行模式
   re.S  表示.(点)包括换行符
在内的任意字符
re.U?表示特殊字符集 w, W, , B, d, D, s, S 依赖于 Unicode 字符属性数据库
    re.X 为了增加可读性,忽略空格和#后面的注释
pattern正则表达式对象的属性、方法
Pattern正则表达式对象是一个编译好的正则表达式对象,通过re.compile()编译后的结果

>>> dir(pattern)
[‘__class__‘, ‘__copy__‘, ‘__deepcopy__‘, ‘__delattr__‘, ‘__dir__‘, ‘__doc__‘, ‘__eq__‘, ‘__format__
‘, ‘__ge__‘, ‘__getattribute__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘, ‘__init_subclass__‘, ‘__le__‘, ‘_
_lt__‘, ‘__ne__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__sizeof__‘,
 ‘__str__‘, ‘__subclasshook__‘, ‘findall‘, ‘finditer‘, ‘flags‘, ‘fullmatch‘, ‘groupindex‘, ‘groups‘,
 ‘match‘, ‘pattern‘, ‘scanner‘, ‘search‘, ‘split‘, ‘sub‘, ‘subn‘]

flags 属性
表示编译时候的匹配模式,
re.compile(pattern[, flags])
flags 可选,表示匹配模式
   re.I 忽略大写写
   re.L 表示特殊字符集,w, W, , B, s, S 依赖当前环境
   re.M 多行模式
   re.S  表示.(点)包括换行符
在内的任意字符
re.U?表示特殊字符集 w, W, , B, d, D, s, S 依赖于 Unicode 字符属性数据库
    re.X 为了增加可读性,忽略空格和#后面的注释

>>> p = re.compile(r"(w+)(w+)(?P<sign>.*)",re.S)
>>> print(p.flags)
48

以上是关于正则的学习的主要内容,如果未能解决你的问题,请参考以下文章

python基础学习(十三)

python基础学习笔记(十三)

text 正则表达式片段

markdown 正则表达式模式片段

正则表达式匹配特定的 URL 片段而不是所有其他 URL 可能性

第43天python学习re模块学习