正则表达式

正则表达式(Regular Expression)

是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")。
正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。
正则表达式是繁琐的,但它是强大的,学会之后的应用会让你除了提高效率外,会给你带来绝对的成就感。

为什么使用正则表达式?

典型的搜索和替换操作要求您提供与预期的搜索结果匹配的确切文本。虽然这种技术对于对静态文本执行简单搜索和替换任务可能已经足够了,但它缺乏灵活性,若采用这种方法搜索动态文本,即使不是不可能,至少也会变得很困难。
通过使用正则表达式,可以:

  • 测试字符串内的模式。
    例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。
  • 替换文本。
    可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。
  • 基于模式匹配从字符串中提取子字符串。
  • 可以查找文档内或输入域内特定的文本。
    例如,您可能需要搜索整个网站,删除过时的材料,以及替换某些 HTML 格式标记。在这种情况下,可以使用正则表达式来确定在每个文件中是否出现该材料或该 HTML 格式标记。此过程将受影响的文件列表缩小到包含需要删除或更改的材料的那些文件。然后可以使用正则表达式来删除过时的材料。最后,可以使用正则表达式来搜索和替换标记。

使用择一符号匹配多个正则表达式。

(|):表示择一匹配的管道符号,表示从多个模式中选择其一的操作。表示并或者逻辑或。

匹配任意单个字符。

(.):匹配除了换行符\n以外的任何字符。
比如: f.o 表示匹配在f和o之间的任一字符,比如fao、f9o、f*o。
.. 匹配任意两个字符。
如果要匹配. 要加转义符\

从字符串起始或结束或单词边界匹配。

如果要匹配字符串的开始位置,就必须使用脱字符(^)或者特殊字符\A。
如果要匹配字符串的结束位置,就必须使用($)或者\Z。
比如:^From 表示任何以From起始的字符串。
/bin/tcsh$ 表示任何以/bin/tcsh作为结尾的字符串。
^Subject:hi$ 表示任何由单独的字符串Subject:hi构成的字符串。
\b和\B可以匹配字符边界。\b用于匹配一个单词的边界。\B匹配出现在一个单词中间的模式。
比如:the 任何包含the的字符串;
\bthe 任何以the开始的字符串;
\bthe\b 仅仅匹配单词the;
\Bthe 任何包含但不以the作为起始的字符串。

创建字符集。

句点可以匹配任意符号,用方括号。
比如 b[aeiu]t 匹配的字符为bat、bet、bit、but。
[cr][23][dp][o2] 匹配的字符为c2do、r3p2等等。。

限定范围和否定

方括号中间用(-)连接,用于指定一个字符的范围。比如A-Z,a-z或者0-9。
另外,如果脱字符^紧跟在左方括号后面,这个符号就表示不匹配给定字符串中的任何一个字符。
比如:z.[0-9] 表示z后面跟着任何一个字符,然后跟着一个数字。
[r-u][env-y][us] 表示r,s,t或者u后面跟着e,n,v,w,x或者y,然后跟着u或s
[^aeiou] 表示一个非元音字符。
[^\t\n] 表示不匹配制表符或换行符。
[“-a] 在一个ASCII系统中,所有字符都位于“”和“a”之间,即34-97之间。

使用闭包操作符实现存在性和频数匹配。

*、+、和? 可用于匹配一个、多个或没有出现的字符串模式。
* 将匹配其左边的正则表达式出现0次或多次的情况。
+ 将匹配一次或多次的正则表达式。
?将匹配前面0次或一次出现的正则表达式。
{} 里面是单个值或者是一对由逗号分隔的值。这将匹配前面的正则表达式N次(如果是{N})或者是一定范围的次数;例如{M,N}。M到N范围之间任意次数。
[dn]ot? d或者n后面跟着o,然后是最多一个t,例如do、no、dot、not
0?[1-9] 任何数值数字,它可能前置一个0。
[0-9]{15,16} 匹配15或者16个数字。
</?[^>]+> 匹配全部有效的(和无效的)HTML标签。

表示字符集的特殊字符。

d 表示匹配任何十进制数字。
(\w) 表示全部字母数字的字符集,相当于[A-Za-z0-9_]的缩写。
\s 表示空格字符。
以上三个的大写形式表示不匹配。
比如:\w+-\d+ 表示一个由字母数字组成的字符串和一串由一个连字符分隔的数字。
[A-Za-z]w* 表示一个字母,其余字符(如果存在)可以是字母或数字。
\d{3}-\d{3}-\d{4} 比如800-55-2412
\w+@\w+.com 比如1042588405@qq.com

使用圆括号指定分组

圆括号有两个功能:对正则表达式进行分组;匹配子组。
\d+(\.\d*)? 表示简单浮点数的字符串,比如0.004、2、75.
(Mr?S?.)?[A-Z][a-z]*[A-Za-z-]+ 名字和姓氏,以及对名字的限制(如果有,首字母必须大写),全名前可以有可选的”Mr”、”Mrs.”、”Ms.”或”M.”。

扩展表示法

(?:\w+.)* 比如goole.、twitter. 但是这些匹配不会被保存供后续使用和数据检索。
(?#comment) 此处并不匹配,只是注释。
(?=.com) 如果一个字符串后面跟着.com才匹配,并不使用任何目标字符串。
(?!.net) 如果一个字符串后面不是跟着.net才做匹配。
(?<=800-) 如果字符串之前是800-才匹配,并不使用任何输入字符串。
(?<!192.168.) 如果一个字符串之前不是192.168才做匹配。
(?(1)y|x) 如果一个匹配组1(\1)存在就与y匹配,否则与x。

Python中的正则表达式

  1. 使用compile()函数编译正则表达式。
  2. 匹配对象以及group()、groups()方法
    group()要么返回整个匹配对象要么根据要求返回特定子组。groups()仅返回一个包含唯一或者全部子组的元组。
  3. 使用match()方法匹配字符串。
    该方法试图从字符串起始部分对模式进行匹配,成功则返回匹配对象,失败返回None。匹配对象的group()方法能够显示那个成功的匹配。

    如果不加if语句,匹配不成功会报错。
  4. 使用search()在一个字符串中查找模式。
    想要搜索的模式出现在字符串中间部分的概率远大于出现在起始部分,这时候可以用search()。它的工作方式和match一样,不同之处在于它会用它的字符串参数,在任意位置对给定正则表达式模式搜索第一次出现匹配的情况。

  5. 匹配多个字符串
  6. 匹配任何单个字符
    .号不能匹配一个换行符或者非字符,即一个空字符串。
  7. 创建字符集([])
  8. 重复、特殊字符以及分组。
    注意group和groups。

    模式中有子组才能用groups,否则是空元组。
  9. 匹配字符串的起始和结尾以及单词边界。

    上面的边界指the的边界,\b匹配以the起始有边界的字符串,\B是不以the为起始的字符串。
  10. 使用findall()和finditer()查找一次出现的位置。
    Findall()查询字符串中某个正则表达式模式全部的非重复出现情况。返回一个列表。
  11. 使用sub()和subn()搜索与替换。
    后者返回总替换的个数且是一个元组。
  12. 在限定模式上使用split()分隔字符串。


    注意?:和?=的用法。
  13. 扩展符号

    (^th[\w ]+) 表示开头是th,后面是任意字符或者空格就一直匹配。
    re.I/IGNORECASE忽略大小写(?i)。
    re.M/MULTILINE实现多行混合搜索
    re.S/DOTALL。该标记表明点号(.)能够用来表示\n 符号。

    re.X/VERBOSE 该标记允许用户通过抑制在正则表达式中使用空白符(除了在字符类中或者在反斜线转义中)来创建更易读的正则表达式
    有了(?x)正则表达式可以换行

    (?:...) 该符号可以对部分正则表达式进行分组,但是并不会保证该分组用于后续的检索或应用。

    可以同时使用(?P)和(?P=name)。
    前者使用一个名称标识符而不是从1开始增加到N的增量数字来保存匹配,如果使用数字来保存匹配结果,可以通过使用\1,\2,...\N来检索(后者)。如下所示:

    后者可以在一个相同的正则表达式中重用模式,而不必再相同的正则表达式指定相同的模式。

    可以用(?x)写成多行正则表达式。

    可以使用(?=...)和(?!...)在目标字符串中实现一个前视匹配,而不必使用这些字符串。前者是正向前视断言,后者是负向前视断言。
    下面代码仅仅对“van Rossum”的名字感兴趣,忽略noreply或postmaster开头的邮件地址。
    第三个代码片段演示了findall和finditer的区别:使用后者来构建一个使用相同登录名但不同域名的邮件地址列表。


    下面是条件正则表达式匹配。假定有另一个特殊字符,仅仅包含x、y,我们此时仅仅想要这样限定字符串:两字母的字符串必须由一个字母跟着另一个字母。
posted @ 2021-03-29 15:18  KKKyrie  阅读(120)  评论(0编辑  收藏  举报