python如何实现识别字符串为AAAB型

2020-09-16 20:00发布

比如 输入 3334 或4333 3433 3343 如何识别成功呢?

比如 输入 3334 或4333 3433 3343 如何识别成功呢?

2条回答
送你小红花
2楼 · 2020-09-18 10:25




匹配包含换行符(回车)的任意字符串的正则表达式

正则表达式Java 

匹配包含换行符(回车)的任意字符串的正则表达式

1)[\s\S]

2)Pattern.DOTALL  \s

匹配字符串的过程中经常会用到能够匹配包含换行符(回车)的任意字符串的正则表达式,即:[\s\S]*

Java代码 收藏代码

  Stringregex="[\\s\\S]*?"; 

但是一般都会匹配形如:A任意字符B这样的模式

这时需要这样使用:正则表达式A[\s\S]*?正则表达式B

例如:

Java代码 收藏代码

  Stringregex=""; 

======================

Pattern.DOTALL

今天也碰到了这个问题,困扰我很久,最后得知,在默认的情况下,字符‘.’不包括换行符。但是可以更改此设置,让字符‘.’表示所以字符:比如:

Patternp=Pattern.compile("regex",Pattern.DOTALL);

p.matcher(content).matches();

设置了Pattern.DOTALL后,就可以了 

========================

([\s\S]*)

同时,也可以用“([\d\D]*)”、“([\w\W]*)”来表示。

在文本文件里,这个表达式可以匹配所有的英文

/[-~]/

这个表达式可以匹配所有的非英文(比如中文)

/[^-~]/

/是VI里用的.你在editplus或程序里不需要/ 

=================

错误的写法

[.\r]

===============

http://www.jb51.net/article/36172.htm

php正则表达式使用的详细介绍

作者:字体:[增加减小]类型:转载时间:2013-04-27我要评论

本篇文章介绍了,php正则表达式使用的详细说明。需要的朋友参考下

前言

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

 1.引子

  目前,正则表达式已经在很多软件中得到广泛的应用,包括*nix(Linux,Unix等),HP等操作系统,PHP,C#,Java等开发环境,以及很多的应用软件中,都可以看到正则表达式的影子。

  正则表达式的使用,可以通过简单的办法来实现强大的功能。为了简单有效而又不失强大,造成了正则表达式代码的难度较大,学习起来也不是很容易,所以需要付出一些努力才行,入门之后参照一定的参考,使用起来还是比较简单有效的。

  例子:^.+@.+\\..+$

  这样的代码曾经多次把我自己给吓退过。可能很多人也是被这样的代码给吓跑的吧。继续阅读本文将让你也可以自由应用这样的代码。

  注意:这里的第7部分跟前面的内容看起来似乎有些重复,目的是把前面表格里的部分重新描述了一次,目的是让这些内容更容易理解。

2.正则表达历史

  正则表达式的“祖先”可以一直上溯至对人类神经系统如何工作的早期研究。WarrenMcCulloch和WalterPitts这两位神经生理学家研究出一种数学方式来描述这些神经网络。

  1956年,一位叫StephenKleene的数学家在McCulloch和Pitts早期工作的基础上,发表了一篇标题为“神经网事件的表示法”的论文,引入了正则表达式的概念。正则表达式就是用来描述他称为“正则集的代数”的表达式,因此采用“正则表达式”这个术语。

  随后,发现可以将这一工作应用于使用KenThompson的计算搜索算法的一些早期研究,KenThompson是Unix的主要发明人。正则表达式的第一个实用应用程序就是Unix中的qed编辑器。

  如他们所说,剩下的就是众所周知的历史了。从那时起直至现在正则表达式都是基于文本的编辑器和搜索工具中的一个重要部分。

3.正则表达式定义

  正则表达式(regularexpression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。

    列目录时, dir*.txt或ls*.txt中的*.txt就不是一个正则表达式,因为这里*与正则式的*的含义是不同的。

  正则表达式是由普通字符(例如字符a到z)以及特殊字符(称为元字符)组成的文字模式。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。

3.1字符

 1、普通字符:

      由所有那些未显式指定为元字符的打印和非打印字符组成。这包括所有的大写和小写字母字符,所有数字,所有标点符号以及一些符号。

 2、非打印字符:

字符 含义

\cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的'c'字符。

\f 匹配一个换页符。等价于\x0c和\cL。

 匹配一个换行符。等价于\x0a和\cJ。

\r 匹配一个回车符。等价于\x0d和\cM。

\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于[\f\r\t\v]。

\S 匹配任何非空白字符。等价于[^\f\r\t\v]。

\t 匹配一个制表符。等价于\x09和\cI。

\v 匹配一个垂直制表符。等价于\x0b和\cK。

3、元字符(特殊字符):

  所谓元字符(特殊字符),就是一些有特殊含义的字符,如上面说的"*.txt"中的*,简单的说就是表示任何字符串的意思。如果要查找文件名中有*的文件,则需要对*进行转义,即在其前加一个\。ls\*.txt。正则表达式有以下特殊字符。

     要在正则表达式模式中包含元字符以使其不具有特殊含义,您必须使用反斜杠(\)转义字符。例如,下面的正则表达式与顺序依次为字母A、字母B、星号和字母C的模式匹配:

     /AB\*C/;

元字符 说明

$ 匹配输入字符串的结尾位置。如果设置了RegExp对象的Multiline属性,则$也匹配''或'\r'。要匹配$字符本身,请使用\$。

() 标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用\(和\)。

* 匹配前面的子表达式零次或多次。要匹配*字符,请使用\*。

+ 匹配前面的子表达式一次或多次。要匹配+字符,请使用\+。

. 匹配除换行符之外的任何单字符。要匹配.,请使用\。

[ 标记一个中括号表达式的开始。要匹配[,请使用\[。

? 匹配前面的子表达式零次或一次,或指明一个非贪婪限定符。要匹配?字符,请使用\?。

\ 将下一个字符标记为或特殊字符、或原义字符、或向后引用、或八进制转义符。例如,'n'匹配字符'n'。''匹配换行符。序列'\\'匹配"\",而'\('则匹配"("。

^ 匹配输入字符串的开始位置,除非在方括号表达式中使用,此时它表示不接受该字符集合。要匹配^字符本身,请使用\^。

{ 标记限定符表达式的开始。要匹配{,请使用\{。

| 指明两项之间的一个选择。要匹配|,请使用\|。

      构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与操作符将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。

4、限定符:

    限定符用来指定正则表达式的一个给定组件必须要出现多少次才能满足匹配。有*或+或?或{n}或{n,}或{n,m}共6种。

*、+和?限定符都是贪婪的,因为它们会尽可能多的匹配文字,只有在它们的后面加上一个?就可以实现非贪婪或最小匹配。

  正则表达式的限定符有:

 

字符 描述

* 匹配前面的子表达式零次或多次。例如,zo*能匹配"z"以及"zoo"。*等价于{0,}。

+ 匹配前面的子表达式一次或多次。例如,'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?'。请注意在逗号和两个数之间不能有空格。 

 5、定界符:边界

    用来描述字符串或单词的边界,^和$分别指字符串的开始与结束,\b描述单词的前或后边界,\B表示非单词边界。不能对定位符使用限定符。

3.2字符类[]

    可以使用字符类指定字符列表以匹配正则表达式中的一个位置。使用方括号([和])定义字符类。例如,下面的正则表达式定义了匹配bag、beg、big、bog或bug的字符类:

  /b[aeiou]g/

1、字符类中的转义序列:

    通常在正则表达式中具有特殊含义的大多数元字符和元序列在字符类中“不具有”那些特殊含义。例如,在正则表达式中星号用于表示重复,但是出现在字符类中时则不具有此含义。下列字符类匹配星号本身以及列出的任何其它字符:

    /[abc*123]/

    但是,下表中列出的三个字符功能与元字符相同,在字符类中具有特殊含义:

  ]  :定义字符类的结尾。

  - :定义字符范围

  \  :定义元序列并撤销元字符的特殊含义。

对于要识别为字面字符(无特殊元字符含义)的任何字符,必须在该字符前面加反斜杠转义字符。例如,下面的正则表达式包含匹配四个符号($、\、]或-)中任意一个符号的字符类。

/[$\\\]\-]/

2、字符类中字符的范围:

    使用连字符指定字符的范围,例如A-Z、a-z或0-9。这些字符必须在字符类中构成有效的范围。例如,下面的字符类匹配a-z范围内的任何一个字符或任何数字:

/[a-z0-9]/

   您还可以使用\xnnASCII字符代码通过ASCII值指定范围。例如,下面的字符类匹配扩展ASCII字符集中的任意字符(如é和ê):

/[\x80-\x9A]/

3、反转的字符类:

    如果在字符类的开头使用尖号(^)字符,则将反转该集合的意义,即未列出的任何字符都认为匹配。下面的字符类匹配除小写字母(a-z)或数字以外的任何字符:

    /[^a-z0-9]/

   必须在字符类的“开头”键入尖号(^)字符以表示反转。否则,您只是将尖号字符添加到字符类的字符中。例如,下面的字符类匹配许多符号字符中的任意一个,其中包括尖号:

   /[!.,#+*%$&^]/

3.3分组和选择

  用圆括号将所有选择项括起来,相邻的选择项之间用|分隔。但用圆括号会有一个副作用,是相关的匹配会被缓存,此时可用?:放在第一个选项前来消除这种副作用。

  其中?:是非捕获元之一,还有两个非捕获元是?=和?!,这两个还有更多的含义,前者为正向预查,在任何开始匹配圆括号内的正则表达式模式的位置来匹配搜索字符串,后者为负向预查,在任何开始不匹配该正则表达式模式的位置来匹配搜索字符串。

     例如:/(very)+/可以匹配verygoogd或者veryverygood

1、后向引用(逆向引用):

  如果在模式中定义标准括号组,则之后可以在正则表达式中引用它。这称为“逆向引用”,并且此类型的组称为“捕获组”。

     对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容存储。存储子匹配的缓冲区编号从1开始,连续编号直至最大99个子表达式。每个缓冲区都可以使用''访问,其中n为一个标识特定缓冲区的一位或两位十进制数。

  例如,在下面的正则表达式中,序列\1匹配在捕获括号组中匹配的任意子字符串:

      /(\d+)-by-\1/; //匹配字符串:48-by-48

     可以通过键入\1,\2,...,\99在正则表达式中指定最多99个此类逆向引用。

    可以使用非捕获元字符'?:','?=',or'?!'来忽略对相关匹配的保存。

2、使用非捕获组和向前查找组:

   非捕获组是只用于分组的组,它不会被“收集”,也不会匹配有限的逆向引用。可以使用(?:和?!)来定义非捕获组,如下所示:

    /(?:com|org|net);

   例如,注意在捕获组和非捕获组中加入(com|org)的区别(使用php来演示):

   捕获组):

复制代码代码如下:

  $pattern='/(\w+)@(\w+).(com|org)/'; 

  $str="bob@example.com"; 

  preg_match($pattern,$str,$match); 

  print_r($match); 

Array

(

  [0]=>bob@example.com

  [1]=>bob

  [2]=>example

  [3]=>com

)

    非捕获组):

复制代码代码如下:

  $pattern='/(\w+)@(\w+).(?:com|org)/'; 

  $str="bob@example.com"; 

  preg_match($pattern,$str,$match); 

  print_r($match); 

 Array

(

  [0]=>bob@example.com

  [1]=>bob

  [2]=>example

)

     一类特殊的非捕获组是“向前查找组”,它包括两种类型:“正向前查找组”和“负向前查找组”。 使用(?=和?!)定义正向前查找组,它指定组中的子模式位置必须匹配。但是,匹配正向前查找组的字符串部分可能匹配正则表达式中的剩余模式。例如,由于(?=e)在下列代码中是正向前查找组,它匹配的字符e可以被正则表达式的后续部分匹配,在本例中为捕获组\w*):

 

复制代码代码如下:

   $pattern='/sh(?=e)(\w*)/i'; 

  $str="Shellysellsseashellsbytheseashore"; 

  preg_match($pattern,$str,$match); 

  print_r($match); 

 

Array

(

  [0]=>Shelly

  [1]=>elly

)

   使用(?!和)定义负向前查找组,它指定该组中的子模式位置必须不匹配。例如:

    模式:$pattern='/sh(?!e)(\w*)/i';

Array

(

  [0]=>shore

  [1]=>ore

)

3.2模式修正标志符

此外还有:

U:表示PCRE_UNGREEDY,表示非贪婪,相当于perl/python语言的.*?,在匹配过程中,对于.*正则,一有匹配立即执行,而不是等.*消费了所有字符再一一回退。

PHP正则表达式模式后面通常带有/i,/is,/s,/isU等参数,那么这都是些什么东西呢?下面我们一起来看看:

模式修正符--解说正则表达式模式中使用的修正符

说明

  下面列出了当前在PCRE中可能使用的修正符。括号中是这些修正符的内部PCRE名。修正符中的空格和换行被忽略,其它字符会导致错误。

i(PCRE_CASELESS)

  如果设定此修正符,模式中的字符将同时匹配大小写字母。

m(PCRE_MULTILINE)

  默认情况下,PCRE将目标字符串作为单一的一“行”字符所组成的(甚至其中包含有换行符也是如此)。“行起始”元字符(^)仅仅匹配字符串的起始,“行结束”元字符($)仅仅匹配字符串的结束,或者最后一个字符是换行符时其前面(除非设定了D修正符)。这和Perl是一样的。

  当设定了此修正符,“行起始”和“行结束”除了匹配整个字符串开头和结束外,还分别匹配其中的换行符的之后和之前。这和Perl的/m修正符是等效的。如果目标字符串中没有“”字符或者模式中没有^或$,则设定此修正符没有任何效果。

s(PCRE_DOTALL)

  如果设定了此修正符,模式中的圆点元字符(.)匹配所有的字符,包括换行符。没有此设定的话,则不包括换行符。这和Perl的/s修正符是等效的。排除字符类例如[^a]总是匹配换行符的,无论是否设定了此修正符。

x(PCRE_EXTENDED)

  如果设定了此修正符,模式中的空白字符除了被转义的或在字符类中的以外完全被忽略,在未转义的字符类之外的#以及下一个换行符之间的所有字符,包括两头,也都被忽略。这和Perl的/x修正符是等效的,使得可以在复杂的模式中加入注释。然而注意,这仅适用于数据字符。空白字符可能永远不会出现于模式中的特殊字符序列,例如引入条件子模式的序列(?(中间。

e

  如果设定了此修正符,preg_replace()在替换字符串中对逆向引用作正常的替换,将其作为PHP代码求值,并用其结果来替换所搜索的字符串。

  只有preg_replace()使用此修正符,其它PCRE函数将忽略之。

  注:本修正符在PHP3中不可用。

A(PCRE_ANCHORED)

  如果设定了此修正符,模式被强制为“anchored”,即强制仅从目标字符串的开头开始匹配。此效果也可以通过适当的模式本身来实现(在Perl中实现的唯一方法)。

D(PCRE_DOLLAR_ENDONLY)

  如果设定了此修正符,模式中的美元元字符仅匹配目标字符串的结尾。没有此选项时,如果  最后一个字符是换行符的话,美元符号也会匹配此字符之前(但不会匹配任何其它换行符之前)。如果设定了m修正符则忽略此选项。Perl中没有与其等价的修正符。

S

  当一个模式将被使用若干次时,为加速匹配起见值得先对其进行分析。如果设定了此修正符则会进行额外的分析。目前,分析一个模式仅对没有单一固定起始字符的non-anchored模式有用。

U(PCRE_UNGREEDY)

  本修正符反转了匹配数量的值使其不是默认的重复,而变成在后面跟上“?”才变得重复。这和Perl不兼容。也可以通过在模式之中设定(?U)修正符或者在数量符之后跟一个问号(如.*?)来启用此选项。

    例如:

复制代码代码如下:

 

  $str='src="http://www.test.cn/1.mp3"type="application/x-mplayer2"test,3333'; 

  echopreg_replace('/src="(.*)"/','--',$str); 

  echo'
'; 

  echopreg_replace('/src="(.*)"/U','--',$str); 

  echo'
'; 

  echopreg_replace('/src="(.*?)"/','--',$str);//等效preg_replace('|src="(.*)"|U','--',$str); 

结果:

--test,3333

--type="application/x-mplayer2"test,3333

--type="application/x-mplayer2"test,3333

从这里我们就可以看出,第一个执行结果一直匹配到最后一个满足条件的字符,专业一点就叫贪婪匹配,

第二个执行结果只匹配第一个满足条件的字符,叫非贪婪匹配。

X(PCRE_EXTRA)

  此修

Anonyem
3楼 · 2020-09-21 14:50







文章目录

简介正则表达式语法模块内容正则表达式对象(正则对象)匹配对象正则表达式例子检查对子模拟scanf()search()vs.match()建立一个电话本文字整理找到所有副词找到所有副词和位置原始字符记法写一个词法分析器




简介

这个模块提供了与Perl语言类似的正则表达式匹配操作。

要搜索的样式和字符串可以是Unicode字符串(str)以及8位字节串(bytes)。但是,Unicode字符串与8位字节串不能混用:也就是说,你不能用一个字节串样式去匹配Unicode字符串,反之亦然;类似地,当进行替换操作时,替换字符串必须与所用的样式和搜索字符串都为相同类型。

正则表达式使用反斜框字符('\')来提示特殊形式或是允许使用特殊字符而又不启用它们的特殊含义。这会与Python在字符串字面值中出于相同目的而使用的相同字符发生冲突;例如,为了匹配一个反斜杠字面值,样式字符串就需要写成'\\\\',因为正则表达式必须写成\\,而每个反斜杠在普通的Python字符串字面值内又必须写成\\。

解决办法是对于正则表达式样式使用Python的原始字符串表示法;在带有'r'前缀的字符串字面值中,反斜杠不必做任何特殊处理。因此r``表示包含``\和n两个字符的字符串,而则表示只包含一个换行符的字符串。样式在Python代码中通常都会使用这种原始字符串表示法来表示。

绝大部分正则表达式操作都提供为模块函数和方法,这些函数是一个捷径,不需要先编译一个正则对象,但是损失了一些优化参数。

参见:第三方模块regex,提供了与标准库re模块兼容的API接口,同时还提供了额外的功能和更全面的Unicode支持。

正则表达式语法

一个正则表达式(或RE)指定了一集与之匹配的字符串;模块内的函数可以让你检查某个字符串是否跟给定的正则表达式匹配(或者一个正则表达式是否匹配到一个字符串,这两种说法含义相同)。

正则表达式可以拼接;如果A和B都是正则表达式,那么AB也是正则表达式。通常,如果字符串p匹配A并且另一个字符串q匹配B,那么pq可以匹配AB。除非A或者B包含低优先级操作,A和B存在边界条件,或者命名组引用。所以,复杂表达式可以很容易的从这里描述的简单源语表达式构建。

以下是正则表达式格式的简要说明。更详细的信息和演示,参考RegularExpressionHOWTO。

正则表达式可以包含普通或者特殊字符。绝大部分普通字符,比如A,a,或者0,都是最简单的正则表达式。它们就匹配自身。你可以拼接普通字符,所以last匹配字符串'last'。(在这一节的其他部分,我们将用thisspecialstyle这种方式表示正则表达式,通常不带引号,要匹配的字符串用'insinglequotes',单引号形式。)

有些字符,比如|或者(,属于特殊字符。特殊字符既可以表示它的普通含义,也可以影响它旁边的正则表达式的解释。

重复修饰符(*,+,?,{m,n},等)不能直接嵌套。这样避免了非贪婪后缀?修饰符和其他实现中的修饰符产生的多义性。要应用一个内层重复嵌套,可以使用括号。比如,表达式(?:a{6})*匹配6个'a'字符重复任意次数。

特殊字符:

.(点)在默认模式,匹配除了换行的任意字符。如果指定了标签DOTALL,它将匹配包括换行符的任意字符。

^(插入符号)匹配字符串的开头,并且在MULTILINE模式也匹配换行后的首个符号。

$匹配字符串尾或者换行符的前一个字符,在MULTILINE模式匹配换行符的前一个字符。foo匹配'foo'和'foobar',但正则foo$只匹配'foo'。更有趣的是,在foo1foo2搜索foo.$,通常匹配'foo2',但在MULTILINE模式,可以匹配到'foo1';在foo搜索$会找到两个空串:一个在换行前,一个在字符串最后。

*对它前面的正则式匹配0到任意次重复,尽量多的匹配字符串。ab*会匹配'a','ab',或者'a'后面跟随任意个'b'。

+对它前面的正则式匹配1到任意次重复。ab+会匹配'a'后面跟随1个以上到任意个'b',它不会匹配'a'。

?对它前面的正则式匹配0到1次重复。ab?会匹配'a'或者'ab'。

*?,+?,??

*,+,和?修饰符都是贪婪的;它们在字符串进行尽可能多的匹配。有时候并不需要这种行为。如果正则式<.*>希望找到b,它将会匹配整个字符串,而不仅是。在修饰符之后添加?将使样式以非贪婪方式或者:dfn:最小方式进行匹配;尽量少的字符将会被匹配。使用正则式<.*?>将会仅仅匹配

{m}对其之前的正则式指定匹配m个重复;少于m的话就会导致匹配失败。比如,a{6}将匹配6个'a',但是不能是5个。

{m,n}对正则式进行m到n次匹配,在m和n之间取尽量多。比如,a{3,5}将匹配3到5个'a'。忽略m意为指定下界为0,忽略n指定上界为无限次。比如a{4,}b将匹配'aaaab'或者1000个'a'尾随一个'b',但不能匹配'aaab'。逗号不能省略,否则无法辨别修饰符应该忽略哪个边界。

{m,n}?前一个修饰符的非贪婪模式,只匹配尽量少的字符次数。比如,对于'aaaaaa',a{3,5}匹配5个'a',而a{3,5}?只匹配3个'a'。

\转义特殊字符(允许你匹配*,?,或者此类其他),或者表示一个特殊序列;特殊序列之后进行讨论。

如果你没有使用原始字符串(r'raw')来表达样式,要牢记Python也使用反斜杠作为转义序列;如果转义序列不被Python的分析器识别,反斜杠和字符才能出现在字符串中。如果Python可以识别这个序列,那么反斜杠就应该重复两次。这将导致理解障碍,所以高度推荐,就算是最简单的表达式,也要使用原始字符串。

[]用于表示一个字符集合。在一个集合中:

字符可以单独列出,比如[amk]匹配'a','m',或者'k'。可以表示字符范围,通过用-将两个字符连起来。比如[a-z]将匹配任何小写ASCII字符,[0-5][0-9]将匹配从00到59的两位数字,[0-9A-Fa-f]将匹配任何十六进制数位。如果-进行了转义(比如[a\-z])或者它的位置在首位或者末尾(如[-a]或[a-]),它就只表示普通字符-。特殊字符在集合中,失去它的特殊含义。比如[(+*)]只会匹配这几个文法字符(,+,*,or)。字符类如\w或者\S(如下定义)在集合内可以接受,它们可以匹配的字符由ASCII或者LOCALE模式决定。不在集合范围内的字符可以通过取反来进行匹配。如果集合首字符是^,所有不在集合内的字符将会被匹配,比如[^5]将匹配除过5的所有字符,[^^]将匹配所有字符,除了'^'。^如果不在集合首位,就没有特殊含义。在集合内要匹配一个字符']',有两种方法,要么就在它之前加上反斜杠,要么就把它放到集合首位。比如,[()[\]{}]和[]()[{}]都可以匹配括号。UnicodeTechnicalStandard里的嵌套集合和集合操作支持可能在未来添加。这将会改变语法,所以为了帮助这个改变,一个FutureWarning将会在有多义的情况里被raise,包含以下几种情况,集合由[开始,或者包含下列字符序列--,&&,~~,和||。为了避免警告,需要将它们用反斜杠转义。


在3.7版更改:如果一个字符串构建的语义在未来会改变的话,一个FutureWarning会raise。


|A|B,A和B可以是任意正则表达式,创建一个正则表达式,匹配A或者B。任意个正则表达式可以用|连接。它也可以在组合(见下列)内使用。扫描目标字符串时,|分隔开的正则样式从左到右进行匹配。当一个样式完全匹配时,这个分支就被接受。意思就是,一旦A匹配成功,B就不再进行匹配,即便它能产生一个更好的匹配。或者说,|操作符绝不贪婪。如果要匹配|字符,使用\|,或者把它包含在字符集里,比如[|]。

(...)(组合),匹配括号内的任意正则表达式,并标识出组合的开始和结尾。匹配完成后,组合的内容可以被获取,并可以在之后用umber转义序列进行再次匹配,之后进行详细说明。要匹配字符'('或者')',用\(或\),或者把它们包含在字符集合里:[(],[)]。

(?…)这是个扩展标记法(一个?跟随(并无含义)。?后面的第一个字符决定了这个构建采用什么样的语法。这种扩展通常并不创建新的组合;(?P...)是唯一的例外。以下是目前支持的扩展。

(?aiLmsux)(a,i,L,m,s,u,x中的一个或多个)这个组合匹配一个空字符串;这些字符对正则表达式设置以下标记:

re.A(只匹配ASCII字符)re.I(忽略大小写)re.L(语言依赖)re.M(多行模式)re.S(点dot匹配全部字符)re.U(Unicode匹配)re.X(冗长模式)

如果你想将这些标记包含在正则表达式中,这个方法就很有用,免去了在re.compile()中传递flag参数。标记应该在表达式字符串首位表示。

(?:…)正则括号的非捕获版本。只识别,不取值。匹配在括号内的任何正则式,但匹配完成后,这个子串不做为结果被获取。比如(?:a)bc指定了匹配样式bc,但这个样式前面必须是字符a,它可以匹配'abc',但不能匹配'bbc',匹配完成后只返回'bc'作为匹配内容。

(?aiLmsux-imsx:…)(a,i,L,m,s,u,x中的0或者多个,之后可选跟随-在后面跟随i,m,s,x中的一到多个)这些字符为表达式的其中一部分设置或者去除相应标记。re.A(只匹配ASCII),re.I(忽略大小写),re.L(语言依赖),re.M(多行),re.S(点匹配所有字符),re.U(Unicode匹配)和re.X(冗长模式)。

a,L和u作为内联标记是相互排斥的,所以它们不能结合在一起,或者跟随-。当他们中的某个出现在内联组中,它就覆盖了括号组内的匹配模式。在Unicode样式中,(?a:...)切换为只匹配ASCII,(?u:...)切换为Unicode匹配(默认)。在bytes样式中(?L:...)切换为语言依赖模式,(?a:...)切换为只匹配ASCII(默认)。这种方式只覆盖组合内匹配,括号外的匹配模式不受影响。


在3.7版更改:符号a,L和u同样可以用在一个组合内。


(?P…)(命名组合)类似正则组合,但是匹配到的子串组在外部是通过定义的name来获取的。组合名必须是有效的Python标识符,并且每个组合名只能用一个正则表达式定义,只能定义一次。一个符号组合同样是一个数字组合,就像这个组合没有被命名一样。

命名组合可以在三种上下文中引用。如果样式是(?P["']).*?(?P=quote)(也就是说,匹配单引号或者双引号括起来的字符串):

引用组合"quote"的上下文引用方法在正则表达式内(?P=quote)\1处理匹配对象*m*m.group('quote')m.end('quote')(等)传递到re.sub()里的repl参数中\g\g<1>\1

(?P=name)反向引用一个命名组合;它匹配前面那个叫name的命名组中匹配到的串同样的字串。

(?#…)注释;里面的内容会被忽略。

(?=…)匹配…的内容,但是并不消费样式的内容。这个叫做lookaheadassertion。比如,Isaac(?=Asimov)只有在Isaac后面是Asimov时才匹配Isaac。

(?!…)匹配…不符合的情况。这个叫negativelookaheadassertion。比如说,Isaac(?!Asimov)只有Isaac后面不是Asimov的时候才匹配Isaac。

(?<=…)匹配字符串的当前位置,它的前面匹配…的内容到当前位置。这叫*positivelookbehindassertion*。(?<=abc)def会在abcdef中找到一个匹配,因为后视会往后看3个字符并检查是否包含匹配的样式。包含的匹配样式必须是定长的,意思就是abc或a|b是允许的,但是a*和a{3,4}不可以。注意以positivelookbehindassertions开始的样式,如(?<=abc)def,并不是从a开始搜索,而是从d往回看的。你可能更加愿意使用search()函数,而不是match()函数。

>>>importre

>>>m=re.search('(?<=abc)def','abcdef')

>>>m.group(0)

'def'


这个例子搜索一个跟随在连字符后的单词:

>>>m=re.search(r'(?<=-)\w+','spam-egg')

>>>m.group(0)

'egg'



在3.5版更改:添加定长组合引用的支持。


(?

(?(id/name)yes-pattern|no-pattern)如果给定的id或name存在,将会尝试匹配yes-pattern,否则就尝试匹配no-pattern,no-pattern可选,也可以被忽略。比如,(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)是一个email样式匹配,将匹配或user@host.com,但不会匹配

由\和一个字符组成的特殊序列在以下列出。如果普通字符不是ASCII数位或者ASCII字母,那么正则样式将匹配第二个字符。比如,\$匹配字符$。

umber匹配数字代表的组合。每个括号是一个组合,组合从1开始编号。比如(.+)\1匹配thethe或者5555,但不会匹配thethe(注意组合后面的空格)。这个特殊序列只能用于匹配前面99个组合。如果number的第一个数位是0,或者number是三个八进制数,它将不会被看作是一个组合,而是八进制的数字值。在[和]字符集合内,任何数字转义都被看作是字符。

\A只匹配字符串开始。

\b匹配空字符串,但只在单词开始或结尾的位置。一个单词被定义为一个单词字符的序列。注意,通常\b定义为\w和\W字符之间,或者\w和字符串开始/结尾的边界,意思就是r'\bfoo\b匹配foo,foo.,(foo),barfoobaz但不匹配foobar或者foo3。

默认情况下,Unicode字母和数字是在Unicode样式中使用的,但是可以用ASCII标记来更改。如果LOCALE标记被设置的话,词的边界是由当前语言区域设置决定的,\b表示退格字符,以便与Python字符串文本兼容。

\B匹配空字符串,但不能在词的开头或者结尾。意思就是r'py\B匹配python,py3,py2,但不匹配py,py.,或者py!。\B是\b的取非,所以Unicode样式的词语是由Unicode字母,数字或下划线构成的,虽然可以用ASCII标志来改变。如果使用了LOCALE标志,则词的边界由当前语言区域设置。

\d

对于Unicode(str)样式:匹配任何Unicode十进制数(就是在Unicode字符目录[Nd]里的字符)。这包括了[0-9],和很多其他的数字字符。如果设置了ASCII标志,就只匹配[0-9]。对于8位(bytes)样式:匹配任何十进制数,就是[0-9]。

\D匹配任何非十进制数字的字符。就是\d取非。如果设置了ASCII标志,就相当于[^0-9]。

\s

对于Unicode(str)样式:匹配任何Unicode空白字符(包括[\t\r\f\v],还有很多其他字符,比如不同语言排版规则约定的不换行空格)。如果ASCII被设置,就只匹配[\t\r\f\v]。对于8位(bytes)样式:匹配ASCII中的空白字符,就是[\t\r\f\v]。

\S匹配任何非空白字符。就是\s取非。如果设置了ASCII标志,就相当于[^\t\r\f\v]。

\w

对于Unicode(str)样式:匹配Unicode词语的字符,包含了可以构成词语的绝大部分字符,也包括数字和下划线。如果设置了ASCII标志,就只匹配[a-zA-Z0-9_]。对于8位(bytes)样式:匹配ASCII字符中的数字和字母和下划线,就是[a-zA-Z0-9_]。如果设置了LOCALE标记,就匹配当前语言区域的数字和字母和下划线。

\W匹配任何非词语字符。是\w取非。如果设置了ASCII标记,就相当于[^a-zA-Z0-9_]。如果设置了LOCALE标志,就匹配当前语言区域的非词语字符。

\Z只匹配字符串尾。

绝大部分Python的标准转义字符也被正则表达式分析器支持:

\a\b\f

\r\t\u\U

\v\x\\



(注意\b被用于表示词语的边界,它只在字符集合内表示退格,比如[\b]。)

\u和\U转义序列只在Unicode样式中支持。bytes样式会显示错误。

八进制转义包含为一个有限形式。如果首位数字是0,或者有三个八进制数位,那么就认为它是八进制转义。其他的情况,就看作是组引用。对于字符串文本,八进制转义最多有三个数位长。


在3.3版更改:增加了\u和\U转义序列。



在3.6版更改:由\和一个ASCII字符组成的未知转义会被看成错误。


模块内容

模块定义了几个函数,常量,和一个例外。有些函数是编译后的正则表达式方法的简化版本(少了一些特性)。绝大部分重要的应用,总是会先将正则表达式编译,之后在进行操作。


在3.6版更改:标志常量现在是RegexFlag类的实例,这个类是enum.IntFlag的子类。


re.compile(pattern,flags=0)

将正则表达式的样式编译为一个正则表达式对象(正则对象),可以用于匹配,通过这个对象的方法match(),search()以及其他如下描述。

这个表达式的行为可以通过指定标记的值来改变。值可以是以下任意变量,可以通过位的OR操作来结合(|操作符)。

表达式语句

prog=re.compile(pattern)

result=prog.match(string)


等价于

result=re.match(pattern,string)


如果需要多次使用这个正则表达式的话,使用re.compile()和保存这个正则对象以便复用,可以让程序更加高效。


注解:通过re.compile()编译后的样式,和模块级的函数会被缓存,所以少数的正则表达式使用无需考虑编译的问题。


re.Are.ASCII

让\w,\W,\b,\B,\d,\D,\s和\S只匹配ASCII,而不是Unicode。这只对Unicode样式有效,会被byte样式忽略。相当于前面语法中的内联标志(?a)。

注意,为了保持向后兼容,re.U标记依然存在(还有他的同义re.UNICODE和嵌入形式(?u)),但是这些在Python3是冗余的,因为默认字符串已经是Unicode了(并且Unicode匹配不允许byte出现)。

re.DEBUG

显示编译时的debug信息,没有内联标记。

re.Ire.IGNORECASE

进行忽略大小写匹配;表达式如[A-Z]也会匹配小写字符。Unicode匹配比如Ü匹配ü)同样有用,除非设置了re.ASCII标记来禁用非ASCII匹配。当前语言区域不会改变这个标记,除非设置了re.LOCALE标记。这个相当于内联标记(?i)。

注意,当设置了IGNORECASE标记,搜索Unicode样式[a-z]或[A-Z]的结合时,它将会匹配52个ASCII字符和4个额外的非ASCII字符:‘İ’(U+0130,拉丁大写的I带个点在上面),‘ı’(U+0131,拉丁小写没有点的I),(U+017F,拉丁小写长s)和‘K’(U+212A,开尔文符号)。如果使用ASCII标记,就只匹配‘a’到‘z’和‘A’到‘Z’。

re.Lre.LOCALE

由当前语言区域决定\w,\W,\b,\B和大小写敏感匹配。这个标记只能对byte样式有效。这个标记不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个“习惯”,而且只对8位字节有效。Unicode匹配在Python3里默认启用,并可以处理不同语言。这个对应内联标记(?L)。


在3.6版更改:re.LOCALE只能用于byte样式,而且不能和re.ASCII一起用。



在3.7版更改:设置了re.LOCALE标记的编译正则对象不再在编译时依赖语言区域设置。语言区域设置只在匹配的时候影响其结果。


re.Mre.MULTILINE

设置以后,样式字符^匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号);样式字符$匹配字符串尾,和每一行的结尾(换行符前面那个符号)。默认情况下,’^’匹配字符串头,$匹配字符串尾。对应内联标记(?m)。

re.Sre.DOTALL

让.特殊字符匹配任何字符,包括换行符;如果没有这个标记,.就匹配除了换行符的其他任意字符。对应内联标记(?s)。

re.Xre.VERBOSE

这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。空白符号会被忽略,除非在一个字符集合当中或者由反斜杠转义,或者在*?,(?:or(?P<…>分组之内。当一个行内有#不在字符集和转义序列,那么它之后的所有字符都是注释。意思就是下面两个正则表达式等价地匹配一个十进制数字:

a=re.compile(r```\d+#theintegralpart

\.#thedecimalpoint

\d*#somefractionaldigits```,re.X)


b=re.compile(r`\d+\.\d*`)


对应内联标记(?x)。

re.search(pattern,string,flags=0)

扫描整个字符串找到匹配样式的第一个位置,并返回一个相应的匹配对象。如果没有匹配,就返回一个None;注意这和找到一个零长度匹配是不同的。

re.match(pattern,string,flags=0)

如果string开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的匹配对象。如果没有匹配,就返回None;注意它跟零长度匹配是不同的。

注意即便是MULTILINE多行模式,re.match()也只匹配字符串的开始位置,而不匹配每行开始。

如果你想定位string的任何位置,使用search()来替代(也可参考search()vs.match())

re.fullmatch(pattern,string,flags=0)

如果整个string匹配到正则表达式样式,就返回一个相应的匹配对象。否则就返回一个None;注意这跟零长度匹配是不同的。


3.4新版功能.


re.split(pattern,string,maxsplit=0,flags=0)

用pattern分开string。如果在pattern中捕获到括号,那么所有的组里的文字也会包含在列表里。如果maxsplit非零,最多进行maxsplit次分隔,剩下的字符全部返回到列表的最后一个元素。

>>>re.split(r'\W+','Words,words,words.')

['Words','words','words','']

>>>re.split(r'(\W+)','Words,words,words.')

['Words',',','words',',','words','.','']

>>>re.split(r'\W+','Words,words,words.',1)

['Words','words,words.']

>>>re.split('[a-f]+','0a3B9',flags=re.IGNORECASE)

['0','3','9']


如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也是一样

>>>re.split(r'(\W+)','...words,words...')

>>>['','...','words',',','words','...','']


这样的话,分隔组将会出现在结果列表中同样的位置。

样式的空匹配将分开字符串,但只在不相临的状况生效。

>>>re.split(r'\b','Words,words,words.')

['','Words',',','words',',','words','.']

>>>re.split(r'\W*','...words...')

['','','w','o','r','d','s','','']

>>>re.split(r'(\W*)','...words...')

['','...','','','w','','o','','r','','d','','s','...','','','']



在3.1版更改:增加了可选标记参数。



在3.7版更改:增加了空字符串的样式分隔。


re.findall(pattern,string,flags=0)

对string返回一个不重复的pattern的匹配列表,string从左到右进行扫描,匹配按找到的顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。


在3.7版更改:非空匹配现在可以在前一个空匹配之后出现了。


re.finditer(pattern,string,flags=0)

pattern在string里所有的非重复匹配,返回为一个迭代器iterator保存了匹配对象。string从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。


在3.7版更改:非空匹配现在可以在前一个空匹配之后出现了。


re.sub(pattern,repl,string,count=0,flags=0)

在string找到的第一个pattern,更换为repl,并返回整个字符串。如果没找到样式,就直接返回string,repl可以是字符串或者函数;如果是字符串,任何转义字符都会被处理。也就是说会转换成换行符,\r会转换为return,其余同理。未知转义比如\&保持原样。向后引用,比如\6,替换为匹配的第六个组。比如

>>>re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',

...r'staticPyObject*py_\1(void){',

...'defmyfunc():')

'staticPyObject*py_myfunc(void){'


如果repl是一个函数,那它会对每个非重复的pattern的情况调用。这个函数只能有一个匹配对象参数,并返回一个替换后的字符串。比如

>>>defdashrepl(matchobj):

...ifmatchobj.group(0)=='-':return''

...else:return'-'

>>>re.sub('-{1,2}',dashrepl,'pro----gram-files')

'pro--gramfiles'

>>>re.sub(r'\sAND\s','&','BakedBeansAndSpam',flags=re.IGNORECASE)

'BakedBeans&Spam'


样式可以是一个字符串或者一个样式对象。

可选参数count是要替换的最大次数;count必须是非负整数。如果忽略这个参数,或者设置为0,所有的匹配都会被替换。空匹配只在不相临连续的情况被更替,所以sub('x*','-','abxd')返回-a-b--d-。

在字符串类型的repl参数里,如上所述的转义和向后引用中,\g会使用命名组合name,(在(?P…)语法中定义)\g会使用数字组;\g<2>就是\2,但它避免了二义性,如\g<2>0。\20就会被解释为组20,而不是组2后面跟随一个字符0。向后引用\g<0>把pattern作为一整个组进行引用。


在3.1版更改:增加了可选标记参数。



在3.5版更改:不匹配的组合替换为空字符串。



在3.6版更改:pattern中的未知转义(由\和一个ASCII字符组成)被视为错误。



在3.7版更改:repl中的未知转义(由\和一个ASCII字符组成)被视为错误。样式中的空匹配相邻接时会被替换。


re.subn(pattern,repl,string,count=0,flags=0)

行为与sub()相同,但是返回一个元组(字符串,替换次数).


在3.1版更改:增加了可选标记参数。



在3.5版更改:不匹配的组合替换为空字符串。


re.escape(pattern)

转义pattern中的特殊字符。如果你想对任意可能包含正则表达式元字符的文本字符串进行匹配,它就是有用的。比如

>>>print(re.escape('python.exe'))

python\.exe

>>>legal_chars=string.ascii_lowercase+string.digits+`!#$%&'*+-.^_`|~:`

>>>print('[%s]+'%re.escape(legal_chars))

[abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+

>>>operators=['+','-','*','/','**']

>>>print('|'.join(map(re.escape,sorted(operators,reverse=True))))

/|\-|\+|\*\*|\*


这个函数不能用在sub()和subn()的替换字符串里,只有反斜杠应该被转义,比如说

>>>digits_re=r'\d+'

>>>sample='/usr/sbin/sendmail-0errors,12warnings'

>>>print(re.sub(digits_re,digits_re.replace('\\',r'\\'),sample))

/usr/sbin/sendmail-\d+errors,\d+warnings



在3.3版更改:_不再被转义。



在3.7版更改:只有在正则表达式中可以产生特殊含义的字符会被转义。


re.purge()

清除正则表达式缓存。

exceptionre.error(msg,pattern=None,pos=None)

raise一个例外。当传递到函数的字符串不是一个有效正则表达式的时候比如,包含一个不匹配的括号)或者其他错误在编译时或匹配时产生。如果字符串不包含样式匹配,是不会被视为错误的。

错误实例有以下附加属性:

msg

未格式化的错误消息。

pattern

正则表达式样式。

pos

编译失败的pattern的位置索引(可以是None)。

lineno

对应pos(可以是None)的行号。

colno

对应pos(可以是None)的列号。


在3.5版更改:添加了附加属性。


正则表达式对象(正则对象)

编译后的正则表达式对象支持一下方法和属性:

Pattern.search(string[,pos[,endpos]])

扫描整个string寻找第一个匹配的位置,并返回一个相应的匹配对象。如果没有匹配,就返回None;注意它和零长度匹配是不同的。可选的第二个参数pos给出了字符串中开始搜索的位置索引;默认为0,它不完全等价于字符串切片;^样式字符匹配字符串真正的开头,和换行符后面的第一个字符,但不会匹配索引规定开始的位置。

可选参数endpos限定了字符串搜索的结束;它假定字符串长度到endpos,所以只有从pos到endpos-1的字符会被匹配。

如果endpos小于pos,就不会有匹配产生;另外,如果rx是一个编译后的正则对象,rx.search(string,0,50)等价于rx.search(string[:50],0)。

>>>pattern=re.compile(`d`)

>>>pattern.search(`dog`)#Matchatindex0

>>>pattern.search(`dog`,1)#Nomatch;searchdoesn'tincludethe`d`


Pattern.match(string[,pos[,endpos]])

如果string的开始位置能够找到这个正则样式的任意个匹配,就返回一个相应的匹配对象。如果不匹配,就返回None;注意它与零长度匹配是不同的。

可选参数pos和endpos与search()含义相同。

>>>pattern=re.compile(`o`)

>>>pattern.match(`dog`)#Nomatchas`o`isnotatthestartof`dog`.

>>>pattern.match(`dog`,1)#Matchas`o`isthe2ndcharacterof`dog`.


如果你想定位匹配在string中的位置,使用search()来替代(另参考search()vs.match())。

Pattern.fullmatch(string[,pos[,endpos]])

如果整个string匹配这个正则表达式,就返回一个相应的匹配对象。否则就返回None;注意跟零长度匹配是不同的。可选参数pos和endpos与search()含义相同。

>>>pattern=re.compile(`o[gh]`)

>>>pattern.fullmatch(`dog`)#Nomatchas`o`isnotatthestartof`dog`.

>>>pattern.fullmatch(`ogre`)#Nomatchasnotthefullstringmatches.

>>>pattern.fullmatch(`doggie`,1,3)#Matcheswithingivenlimits.



3.4新版功能.


Pattern.split(string,maxsplit=0)

等价于split()函数,使用了编译后的样式。

Pattern.findall(string[,pos[,endpos]])

类似函数findall(),使用了编译后样式,但也可以接收可选参数pos和endpos,限制搜索范围,就像search()`。

Pattern.finditer(string[,pos[,endpos]])

类似函数finiter(),使用了编译后样式,但也可以接收可选参数pos和endpos,限制搜索范围,就像search()。

Pattern.sub(repl,string,count=0)

等价于sub()函数,使用了编译后的样式。

Pattern.subn(repl,string,count=0)

等价于subn()函数,使用了编译后的样式。

Pattern.flags

正则匹配标记。这是可以传递给compile()的参数,任何(?…)内联标记,隐性标记比如UNICODE的结合。

Pattern.groups

捕获组合的数量。

Pattern.groupindex

映射由(?P)定义的命名符号组合和数字组合的字典。如果没有符号组,那字典就是空的。

Pattern.pattern

编译对象的原始样式字符串。


在3.7版更改:添加copy.copy()和copy.deepcopy()函数的支持。编译后的正则表达式对象被认为是原子性的。


匹配对象

匹配对象总是有一个布尔值True。如果没有匹配的话match()和search()返回None所以你可以简单的用if语句来判断是否匹配

match=re.search(pattern,string)

ifmatch:

process(match)


匹配对象支持以下方法和属性:

Match.expand(template)

对template进行反斜杠转义替换并且返回,就像sub()方法中一样。转义如同被转换成合适的字符,数字引用(\1,\2)和命名组合(\g<1>,\g)替换为相应组合的内容。


在3.5版更改:不匹配的组合替换为空字符串。


Match.group([group1,…])

返回一个或者多个匹配的子组。如果只有一个参数,结果就是一个字符串,如果有多个参数,结果就是一个元组(每个参数对应一个项),如果没有参数,组1默认到0(整个匹配都被返回)。如果一个组N参数值为0,相应的返回值就是整个匹配字符串;如果它是一个范围[1…99],结果就是相应的括号组字符串。如果一个组号是负数,或者大于样式中定义的组数,一个IndexError索引错误就raise。如果一个组包含在样式的一部分,并被匹配多次,就返回最后一个匹配。:

>>>m=re.match(r`(\w+)(\w+)`,`IsaacNewton,physicist`)

>>>m.group(0)#Theentirematch

'IsaacNewton'

>>>m.group(1)#Thefirstparenthesizedsubgroup.

'Isaac'

>>>m.group(2)#Thesecondparenthesizedsubgroup.

'Newton'

>>>m.group(1,2)#Multipleargumentsgiveusatuple.

('Isaac','Newton')


如果正则表达式使用了(?P…)语法,groupN参数就也可能是命名组合的名字。如果一个字符串参数在样式中未定义为组合名,一个IndexError就raise。

一个相对复杂的例子

>>>m=re.match(r`(?P\w+)(?P\w+)`,`MalcolmReynolds`)

>>>m.group('first_name')

'Malcolm'

>>>m.group('last_name')

'Reynolds'


命名组合同样可以通过索引值引用

>>>m.group(1)

'Malcolm'

>>>m.group(2)

'Reynolds'


如果一个组匹配成功多次,就只返回最后一个匹配

>>>m=re.match(r`(..)+`,`a1b2c3`)#Matches3times.

>>>m.group(1)#Returnsonlythelastmatch.

'c3'


Match.getitem(g)

这个等价于m.group(g)。这允许更方便的引用一个匹配

>>>m=re.match(r`(\w+)(\w+)`,`IsaacNewton,physicist`)

>>>m[0]#Theentirematch

'IsaacNewton'

>>>m[1]#Thefirstparenthesizedsubgroup.

'Isaac'

>>>m[2]#Thesecondparenthesizedsubgroup.

'Newton'



3.6新版功能.


Match.groups(default=None)

返回一个元组,包含所有匹配的子组,在样式中出现的从1到任意多的组合。default参数用于不参与匹配的情况,默认为None。

例如

>>>m=re.match(r`(\d+)\.(\d+)`,`24.1632`)

>>>m.groups()

('24','1632')


如果我们使小数点可选,那么不是所有的组都会参与到匹配当中。这些组合默认会返回一个None,除非指定了default参数。

>>>m=re.match(r`(\d+)\.?(\d+)?`,`24`)

>>>m.groups()#SecondgroupdefaultstoNone.

('24',None)

>>>m.groups('0')#Now,thesecondgroupdefaultsto'0'.

('24','0')


Match.groupdict(default=None)

返回一个字典,包含了所有的命名子组。key就是组名。default参数用于不参与匹配的组合;默认为None。例如

>>>m=re.match(r`(?P\w+)(?P\w+)`,`MalcolmReynolds`)

>>>m.groupdict()

{'first_name':'Malcolm','last_name':'Reynolds'}


Match.start([group])Match.end([group])

返回group匹配到的字串的开始和结束标号。group默认为0(意思是整个匹配的子串)。如果group存在,但未产生匹配,就返回-1。对于一个匹配对象m,和一个未参与匹配的组g,组g(等价于m.group(g))产生的匹配是

m.string[m.start(g):m.end(g)]


注意m.start(group)将会等于m.end(group),如果group匹配一个空字符串的话。

比如,在m=re.search('b(c?)','cba')之后,m.start(0)为1,m.end(0)为2,m.start(1)和m.end(1)都是2,m.start(2)raise一个IndexError例外。

这个例子会从email地址中移除掉remove_this

>>>email=`tony@tiremove_thisger.net`

>>>m=re.search(`remove_this`,email)

>>>email[:m.start()]+email[m.end():]

'tony@tiger.net'


Match.span([group])

对于一个匹配m,返回一个二元组(m.start(group),m.end(group))。注意如果group没有在这个匹配中,就返回(-1,-1)。group默认为0,就是整个匹配。

Match.pos

pos的值,会传递给search()或match()的方法a正则对象。这个是正则引擎开始在字符串搜索一个匹配的索引位置。

Match.endpos

endpos的值,会传递给search()或match()的方法a正则对象。这个是正则引擎停止在字符串搜索一个匹配的索引位置。

Match.lastindex

捕获组的最后一个匹配的整数索引值,或者None如果没有匹配产生的话。比如,对于字符串ab,表达式(a)b,((a)(b)),和((ab))将得到lastindex==1,而(a)(b)会得到lastindex==2。

Match.lastgroup

最后一个匹配的命名组名字,或者None如果没有产生匹配的话。

Match.re

返回产生这个实例的正则对象,这个实例是由正则对象的match()或search()方法产生的。

Match.string

传递到match()或search()的字符串。


在3.7版更改:添加了对copy.copy()和copy.deepcopy()的支持。匹配对象被看作是原子性的。


正则表达式例子

检查对子

在这个例子里,我们使用以下辅助函数来更好的显示匹配对象:

defdisplaymatch(match):

ifmatchisNone:

returnNone

return''%(match.group(),match.groups())


假设你在写一个扑克程序,一个玩家的一手牌为五个字符的串,每个字符表示一张牌,“a”就是A,“k”就是K,“q”就是Q,“j”就是J,“t”为10,“2”到“9”表示2到9。

要看给定的字符串是否有效,我们可以按照以下步骤

>>>valid=re.compile(r`^[a2-9tjqk]{5}$`)

>>>displaymatch(valid.match(`akt5q`))#Valid.

``

>>>displaymatch(valid.match(`akt5e`))#Invalid.

>>>displaymatch(valid.match(`akt`))#Invalid.

>>>displaymatch(valid.match(`727ak`))#Valid.

``


最后一手牌,727ak,包含了一个对子,或者两张同样数值的牌。要用正则表达式匹配它,应该使用向后引用如下

>>>pair=re.compile(r`.*(.).*\1`)

>>>displaymatch(pair.match(`717ak`))#Pairof7s.

``

>>>displaymatch(pair.match(`718ak`))#Nopairs.

>>>displaymatch(pair.match(`354aa`))#Pairofaces.

``


要找到对子包含的是哪一张牌,应该按照下面的方式使用group()方法:

>>>pair.match(`717ak`).group(1)

'7'

#Errorbecausere.match()returnsNone,whichdoesn'thaveagroup()method:

...pair.match(`718ak`).group(1)

Traceback(mostrecentcalllast):

File``,line1,in

re.match(r`.*(.).*\1`,`718ak`).group(1)

AttributeError:'NoneType'objecthasnoattribute'group'

>>>pair.match(`354aa`).group(1)

'a'


模拟scanf()

Python目前没有一个类似c函数scanf()的替代品。正则表达式通常比scanf()格式字符串要更强大一些,但也带来更多复杂性。下面的表格提供了scanf()格式符和正则表达式大致相同的映射。

scanf()格式符正则表达式%c.\.{5}%d[-+]?\d+%e,%E,%f,%g[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?%i[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)%o[-+]?[0-7]+%s\S+%u\d+%x,%X[-+]?(0[xX])?[\dA-Fa-f]+

从文件名和数字提取字符串

/usr/sbin/sendmail-0errors,4warnings


你可以使用scanf()格式化

%s-?rrors,%dwarnings


等价的正则表达式是:

(\S+)-(\d+)errors,(\d+)warnings


search()vs.match()

Python提供了两种不同的操作:基于re.match()检查字符串开头,或者re.search()检查字符串的任意位置(默认Perl中的行为)。

例如

>>>re.match(`c`,`abcdef`)#Nomatch

>>>re.search(`c`,`abcdef`)#Match


在search()中,可以用^作为开始来限制匹配到字符串的首位

>>>re.match(`c`,`abcdef`)#Nomatch

>>>re.search(`^c`,`abcdef`)#Nomatch

>>>re.search(`^a`,`abcdef`)#Match


注意MULTILINE多行模式中函数match()只匹配字符串的开始,但使用search()和以^开始的正则表达式会匹配每行的开始

>>>re.match('X','ABX',re.MULTILINE)#Nomatch

>>>re.search('^X','ABX',re.MULTILINE)#Match


建立一个电话本

split()将字符串用参数传递的样式分隔开。这个方法对于转换文本数据到易读而且容易修改的数据结构,是很有用的,如下面的例子证明。

首先,这里是输入。通常是一个文件,这里我们用三引号字符串语法

>>>text=```RossMcFluff:834.345.1254155ElmStreet

...

...RonaldHeathmore:892.345.3428436FinleyAvenue

...FrankBurger:925.541.7625662SouthDogwoodWay

...

...

...HeatherAlbrecht:548.326.4584919ParkPlace```


条目用一个或者多个换行符分开。现在我们将字符串转换为一个列表,每个非空行都有一个条目:

>>>entries=re.split(`+`,text)

>>>entries

['RossMcFluff:834.345.1254155ElmStreet',

'RonaldHeathmore:892.345.3428436FinleyAvenue',

'FrankBurger:925.541.7625662SouthDogwoodWay',

'HeatherAlbrecht:548.326.4584919ParkPlace']


最终,将每个条目分割为一个由名字、姓氏、电话号码和地址组成的列表。我们为split()使用了maxsplit形参,因为地址中包含有被我们作为分割模式的空格符:

>>>[re.split(`:?`,entry,3)forentryinentries]

[['Ross','McFluff','834.345.1254','155ElmStreet'],

['Ronald','Heathmore','892.345.3428','436FinleyAvenue'],

['Frank','Burger','925.541.7625','662SouthDogwoodWay'],

['Heather','Albrecht','548.326.4584','919ParkPlace']]


:?样式匹配姓后面的冒号,因此它不出现在结果列表中。如果maxsplit设置为4,我们还可以从地址中获取到房间号:

>>>[re.split(`:?`,entry,4)forentryinentries]

[['Ross','McFluff','834.345.1

相关问题推荐

  • 回答 3

    换行。比如,print hello\nworld效果就是helloworld\n就是一个换行符。\是转义的意思,&#39;\n&#39;是换行,&#39;\t&#39;是tab,&#39;\\&#39;是,\ 是在编写程序中句子太长百,人为换行后加上\但print出来是一整行。...

  • 回答 42

    十种常见排序算法一般分为以下几种:(1)非线性时间比较类排序:a. 交换类排序(快速排序、冒泡排序)b. 插入类排序(简单插入排序、希尔排序)c. 选择类排序(简单选择排序、堆排序)d. 归并排序(二路归并排序、多路归并排序)(2)线性时间非比较类排序:...

  • 回答 70
    已采纳

    前景很好,中国正在产业升级,工业机器人和人工智能方面都会是强烈的热点,而且正好是在3~5年以后的时间。难度,肯定高,要求你有创新的思维能力,高数中的微积分、数列等等必须得非常好,软件编程(基础的应用最广泛的语言:C/C++)必须得很好,微电子(数字电...

  • 回答 28

    迭代器与生成器的区别:(1)生成器:生成器本质上就是一个函数,它记住了上一次返回时在函数体中的位置。对生成器函数的第二次(或第n次)调用,跳转到函数上一次挂起的位置。而且记录了程序执行的上下文。生成器不仅记住了它的数据状态,生成器还记住了程序...

  • 回答 9

    python中title( )属于python中字符串函数,返回’标题化‘的字符串,就是单词的开头为大写,其余为小写

  • 回答 6

    第一种解释:代码中的cnt是count的简称,一种电脑计算机内部的数学函数的名字,在Excel办公软件中计算参数列表中的数字项的个数;在数据库( sq| server或者access )中可以用来统计符合条件的数据条数。函数COUNT在计数时,将把数值型的数字计算进去;但是...

  • 回答 1

    head是方法,所以需要取小括号,即dataset.head()显示的则是前5行。data[:, :-1]和data[:, -1]。另外,如果想通过位置取数据,请使用iloc,即dataset.iloc[:, :-1]和dataset.iloc[:, -1],前者表示的是取所有行,但不包括最后一列的数据,结果是个DataFrame。...

  • Python入门简单吗2021-09-23 13:21
    回答 45

    挺简单的,其实课程内容没有我们想象的那么难、像我之前同学,完全零基础,培训了半年,直接出来就工作了,人家还在北京大公司上班,一个月15k,实力老厉害了

  • 回答 4

    Python针对众多的类型,提供了众多的内建函数来处理(内建是相对于导入import来说的,后面学习到包package时,将会介绍),这些内建函数功用在于其往往可对多种类型对象进行类似的操作,即多种类型对象的共有的操作;如果某种操作只对特殊的某一类对象可行,Pyt...

  • 回答 8

     相当于 ... 这里不是注释

  • 回答 4

    还有FIXME

  • 回答 3

    python的两个库:xlrd和xlutils。 xlrd打开excel,但是打开的excel并不能直接写入数据,需要用xlutils主要是复制一份出来,实现后续的写入功能。

  • 回答 8

    单行注释:Python中的单行注释一般是以#开头的,#右边的文字都会被当做解释说明的内容,不会被当做执行的程序。为了保证代码的可读性,一般会在#后面加一两个空格然后在编写解释内容。示例:#  单行注释print(hello world)注释可以放在代码上面也可以放在代...

  • 回答 2

    主要是按行读取,然后就是写出判断逻辑来勘测行是否为注视行,空行,编码行其他的:import linecachefile=open(&#39;3_2.txt&#39;,&#39;r&#39;)linecount=len(file.readlines())linecache.getline(&#39;3_2.txt&#39;,linecount)这样做的过程中发现一个问题,...

  • 回答 4

    或许是里面有没被注释的代码

  • 回答 26

    自学的话要看个人情况,可以先在B站找一下视频看一下

没有解决我的问题,去提问