python 之 re模块(正则表达式)

发布时间:2018-11-19  栏目:w88优德官网电脑版  评论:0 Comments

一、起源(历史)

  正则表达式的“鼻祖”或许只是一直追溯至科学家对人类神经系统办事原理的初研究。美国新泽西州底Warren
McCulloch和落地在美国底特律的Walter
Pitts这半各类神经生理方面的科学家,研究起了一致栽用数学方法来叙述神经网络的新措施,他们创造性地将神经系统受之神经细胞描述成了稍稍而简单的机动控制长,从而作出了千篇一律桩宏大的劳作改革。

  以1956 年,一位叫Stephen Kleene的数学科学家,他在Warren
McCulloch和Walter
Pitts早期工作之基本功之上,发表了一致首题目是《神经网事件的代表拟》的舆论,利用称之为正则集合的数学符号来叙述是模型,引入了正则表达式的定义。正则表达式被看作用来讲述其名为“正则集聚的代数”的如出一辙种植表达式,因而使用了“正则表达式”这个术语。

  之后一段时间,人们发现可以立即无异工作成果应用叫其它地方。Ken
Thompson就将当下同成果运用被计算搜索算法的片最初研究,Ken
Thompson是
Unix的重大发明人,也就算是著名的Unix之大。Unix之大将以此符系统引入编辑器QED,然后是Unix上之编排器ed,并最终引入grep。Jeffrey
Friedl 在那个著述《Mastering Regular Expressions (2nd
edition)》(中文版译作:精通正则表达式,已产生至第三本)中针对之作了进一步阐释讲解,如果您望还多询问正则表达式理论同历史,推荐你省就本书。

  自此以后,正则表达式被广大地使到各种UNIX或近似于UNIX的家伙中,如大家熟悉的Perl。Perl的正则表达式源自于Henry
Spencer编写的regex,之后一度演变成了pcre(Perl兼容正则表达式Perl
Compatible Regular Expressions),pcre是一个是因为Philip
Hazel开发之、为许多现代器所动的仓库。正则表达式的首先只实用应用程序即为Unix中的
qed 编辑器。

  然后,正则表达式在各种计算机语言还是各种应用领域得到了宽广的用及发展,演变成计算机技术森林中之平等单形神美丽且声音好听的百灵鸟。

上述是关于正则表达式的来自和进步之史叙述,如今正则表达式在根据文本的编辑器同摸索工具中仍占着一个十分重大的身份。

  于近年来之六十年被,正则表达式逐渐由模糊而深邃的数学概念,发展变成当处理器各类工具与软件包用被的重中之重功用。不仅仅众多UNIX工具支持正则表达式,近二十年来,在WINDOWS的营垒下,正则表达式的考虑以及动用在多数
Windows 开发者工具确保吃获得支持与搭应用!从正则式在Microsoft Visual
Basic 6 抑或 Microsoft VBScript到.NET
Framework中的追究以及前进,WINDOWS系列产品对正则表达式的支撑提高至无与伦比的冲天,几乎所有
Microsoft
开发者和所有.NET语言都可以动用正则表达式。如果你是平员接触电脑语言的劳动力,那么你会在主流操作系统(*nix[Linux,
Unix等]、Windows、HP、BeOS等)、主流的出语言(delphi、Scala、PHP、C#、Java、C++、Objective-c、Swift、VB、Javascript、Ruby以及Python相当)、数以亿万计的各种应用软件被,都得以见见正则表达式优美之舞姿。

二、概念

  正则表达式是对字符拧操作的一律栽逻辑公式,就是用事先定义好的组成部分一定字符、及这些特定字符的结缘,组成一个“规则字符串”,这个“规则字符串”用来发表对字符串的平种过滤逻辑。

三、引擎(略)

四、字符

  字符分为常见字符和长字符:

  普通字符:包括大小写的字符和数字。

  元字符:(如下)

 

元字符
描述
\
将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\\n”匹配\n。“\n”匹配换行符。序列“\\”匹配“\”而“\(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。
^
匹配输入字符串的开始位置。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$
匹配输入字符串的结束位置。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
*
匹配前面的子表达式任意次。例如,zo*能匹配“z”,也能匹配“zo”以及“zoo”。
+
匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
?
匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。
{n}
n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{n,}
n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{n,m}
m和n均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
?
当该字符紧跟在任何一个其他限制符(*,+,?,{n},{n,},{n,m})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串“oooo”,“o+?”将匹配单个“o”,而“o+”将匹配所有“o”。
.点
匹配除“\r\n”之外的任何单个字符。要匹配包括“\r\n”在内的任何字符,请使用像“[\s\S]”的模式。
(pattern)
匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。
(?:pattern)
非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分是很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern)
非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern)
非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
(?<=pattern)
非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。
(?<!pattern)
非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。这个地方不正确,有问题
x|y
匹配x或y。例如,“z|food”能匹配“z”或“food”(此处请谨慎)。“(z|f)ood”则匹配“zood”或“food”。
[xyz]
字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz]
负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”。
[a-z]
字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。
注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身.
[^a-z]
负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
\b
匹配一个单词边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的)。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”。
\B
匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\cx
匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
\d
匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持
\D
匹配一个非数字字符。等价于[^0-9]。grep要加上-Pperl正则支持
\f
匹配一个换页符。等价于\x0c和\cL。
\n
匹配一个换行符。等价于\x0a和\cJ。
\r
匹配一个回车符。等价于\x0d和\cM。
\s
匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
\S
匹配任何可见字符。等价于[^ \f\n\r\t\v]。
\t
匹配一个制表符。等价于\x09和\cI。
\v
匹配一个垂直制表符。等价于\x0b和\cK。
\w
匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。
\W
匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\xn
匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。
\num
匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。
\n
标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。
\nm
标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。
\nml
如果n为八进制数字(0-7),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。
\un
匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(&copy;)。
\p{P}
小写 p 是 property 的意思,表示 Unicode 属性,用于 Unicode 正表达式的前缀。中括号内的“P”表示Unicode 字符集七个字符属性之一:标点字符。
其他六个属性:
L:字母;
M:标记符号(一般不会单独出现);
Z:分隔符(比如空格、换行等);
S:符号(比如数学符号、货币符号等);
N:数字(比如阿拉伯数字、罗马数字等);
C:其他字符。
*注:此语法部分语言不支持,例:javascript。
< > 匹配词(word)的开始(<)和结束(>)。例如正则表达式<the>能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:这个元字符不是所有的软件都支持的。
( ) 将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。
| 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。
+ 匹配1或多个正好在它之前的那个字符。例如正则表达式9+匹配9、99、999等。注意:这个元字符不是所有的软件都支持的。
? 匹配0或1个正好在它之前的那个字符。注意:这个元字符不是所有的软件都支持的。
{i} {i,j} 匹配指定数目的字符,这些字符是在它之前的表达式定义的。例如正则表达式A[0-9]{3} 能够匹配字符"A"后面跟着正好3个数字字符的串,例如A123、A348等,但是不匹配A1234。而正则表达式[0-9]{4,6} 匹配连续的任意4个、5个或者6个数字

w88优德官网电脑版 1

五、re模块

 re.``compile(patternflags=0)

re.``DEBUG

re.``I

re.``IGNORECASE

re.``L

re.``LOCALE

re.``M

re.``MULTILINE

re.``S

re.``DOTALL

re.``U

re.``UNICODE

re.``X

re.``VERBOSE

re.``search(patternstringflags=0)

re.``match(patternstringflags=0)

re.``split(patternstringmaxsplit=0flags=0)

re.``findall(patternstringflags=0)

re.``finditer(patternstringflags=0)

re.``sub(patternreplstringcount=0flags=0)

re.``subn(patternreplstringcount=0flags=0)

re.``escape(string)

re.``purge()

六、举例

prog = re.compile(pattern)
result = prog.match(string)
等同于   result = re.match(pattern, string)
  1. match(string[, pos[, endpos]]) | re.match(pattern, string[,
    flags]): 
    以此艺术以于string的pos下标处起尝试匹配pattern;如果pattern结束时本只是匹配,则回一个Match对象;如果配合过程遭到pattern无法匹配,或者配合未终止就已经到达endpos,则归None。 
    pos和endpos的默认值分别吗0跟len(string);re.match()无法指定这简单只参数,参数flags用于编译pattern时指定匹配模式。 
    留意:这个办法并无是意匹配。当pattern结束时若string还发剩余字符,仍然视为成功。想只要完全匹配,可以在表达式末尾加上边界匹配符’$’。 
    以身作则参见2.1小节。
  2. search(string[, pos[, endpos]]) | re.search(pattern, string[,
    flags]): 
    这法子用于查找字符串中可以兼容成功的子串。从string的pos下标处起尝试匹配pattern,如果pattern结束时以只是配合,则赶回一个Match对象;若无法配合,则拿pos加1后重新尝试匹配;直到pos=endpos时遵循力不从心配合则赶回None。 
    pos和endpos的默认值分别吗0暨len(string));re.search()无法指定这片单参数,参数flags用于编译pattern时指定匹配模式。 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # encoding: UTF-8
    import re
     
    # 将正则表达式编译成Pattern对象
    pattern = re.compile(r'world')
     
    # 使用search()查找匹配的子串,不存在能匹配的子串时将返回None
    # 这个例子中使用match()无法成功匹配
    match = pattern.search('hello world!')
     
    if match:
        # 使用Match获得分组信息
        print match.group()
     
    ### 输出 ###
    # world
  3. split(string[, maxsplit]) | re.split(pattern, string[,
    maxsplit]): 
    论能兼容的子串将string分割后回列表。maxsplit用于指定最可怜分割次数,不指定将周区划。 

    1
    2
    3
    4
    5
    6
    7
    import re
     
    = re.compile(r'\d+')
    print p.split('one1two2three3four4')
     
    ### output ###
    # ['one', 'two', 'three', 'four', '']
  4. findall(string[, pos[, endpos]]) | re.findall(pattern,
    string[, flags]): 
    招来string,以列表形式返回全部能配合的子串。 

    1
    2
    3
    4
    5
    6
    7
    import re
     
    = re.compile(r'\d+')
    print p.findall('one1two2three3four4')
     
    ### output ###
    # ['1', '2', '3', '4']
  5. finditer(string[, pos[, endpos]]) | re.finditer(pattern,
    string[, flags]): 
    寻找string,返回一个各个访问各国一个配合结果(Match对象)的迭代器。 

    1
    2
    3
    4
    5
    6
    7
    8
    import re
     
    = re.compile(r'\d+')
    for in p.finditer('one1two2three3four4'):
        print m.group(),
     
    ### output ###
    # 1 2 3 
  6. sub(repl, string[, count]) | re.sub(pattern, repl, string[,
    count]): 
    采用repl替换string中各个一个匹的子串后赶回替换后底字符串。 
    当repl是一个字符串时,可以采用\id或\g<id>、\g<name>引用分组,但无克利用编号0。 
    当repl是一个道时,这个主意应该就领一个参数(Match对象),并回一个字符串用于替换(返回的字符串中未克再引用分组)。 
    count用于指定最多替换次数,不指定时全替换。 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import re
     
    = re.compile(r'(\w+) (\w+)')
    = 'i say, hello world!'
     
    print p.sub(r'\2 \1', s)
     
    def func(m):
        return m.group(1).title() + ' ' + m.group(2).title()
     
    print p.sub(func, s)
     
    ### output ###
    # say i, world hello!
    # I Say, Hello World!

    d

  7. subn(repl, string[, count]) |re.sub(pattern, repl, string[,
    count]): 
    返回 (sub(repl, string[, count]), 替换次数)。 

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import re
     
    = re.compile(r'(\w+) (\w+)')
    = 'i say, hello world!'
     
    print p.subn(r'\2 \1', s)
     
    def func(m):
        return m.group(1).title() + ' ' + m.group(2).title()
     
    print p.subn(func, s)
     
    ### output ###
    # ('say i, world hello!', 2)
    # ('I Say, Hello World!', 2)

如上就是Python对于正则表达式的支撑。熟练掌握正则表达式是各一个程序员必须怀有的技巧,这年头没有不跟字符串打交道的顺序了。笔者为处于初级阶段,与天皇共勉,^_^

除此以外,图备受的奇结构部分没举出例子,用到这些的正则表达式是有着自然难度的。有趣味可以考虑一下,如何配合不是为abc开头的单词,^_^

************************************************************************

************************************************************************

正则表达式修饰符 – 可选标志

正则表达式可以涵盖部分不过挑选标志修饰符来控制相当的模式。修饰符被指定为一个可选的标志。多独标志可以透过按位
OR(|) 它们来指定。如 re.I | re.M 被安装成 I 和 M 标志:

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

 
七、具体应用举例:

留下评论