在Python中使用正则表达式的方法

正则表达式(regular expression)是一种用形式化语法描述的文本匹配模式。在需要处理大量文本处理的应用中有广泛的使用,我没使用的编辑器,IDE中的搜索常用正则表达式作为搜索模式。玩过*nix系统的都知道如sed,grep,awk这类的命令,他们是非常强大的文本处理工具。几乎所有的语言都有对正则表达式的支持,有的直接在语法中支持,有的使用扩展库的形式。python使用的就是扩展库re。

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

搜索文本中的匹配的模式是最常用的.以模式和文本作为输入,如果有匹配则返回一个Match对象,反之返回None。
    每个Match对象包括相关的匹配信息:原字符串、正则表达式和匹配的文本在字符串中的位置。

import re
pattern = "this"
text = "Does this text match the pattern?"
match = re.search(pattern, text) # 返回一个Match对象
print match.re.pattern # 要匹配的正则表达式"this"
print match.string   # 匹配的文本"Does this match the pattern?"
print match.start()   # 匹配的开始位置 5
print match.end()    # 匹配的结束位置 9

    re.compile(pattern,flag=0)
    如果程序中频繁的使用到同一个正则表达式,每次使用的时候都写一遍正则表达式不仅不高效而且会大大增加出错的几率,re提供了compile函数将一个表达式字符串编译为一个RegexObject。
    模块级函数会维护已编译表达式的一个缓存,而这个缓存是的大小是有限制的。直接使用已经编译的表达式可以避免缓存查找的开销,并且在加载模块时就会预编译所有的表达式。

import re
regex = re.compile("this")
text = "Does this text match the pattern?"
match = regex.search(text)
if match:
  print "match"
  match.group(0)  #返回匹配的字符串
else:
  print "not match"

    re.findall(pattern, string, flag=0)
    使用search会返回匹配的单个实例,使用findall会返回所有匹配的不重叠的子串。

import re
pattern = 'ab'
text = 'abbaaabbbbaaaaaa'
re.findall(pattern, text)  # 返回['ab', 'ab']

    re.finditer(pattern, string, flag=0)
    finditer会返回一个迭代器,会生成Match实例,不像findall()返回字符串.

import re
pattern = 'ab'
text = 'abbaaabbbbaaaaaa'
match = re.finditer(pattern, text)
for m in match:
  print m.start()
  print m.end()

以上的例子会分别输出两次匹配结果的起始位置和结束位置。

正则匹配默认采用的是贪婪算法,也就是说会re在匹配的时候会利用尽可能多的输入,而使用?可以关闭这种贪心行为,只匹配最少的输入。这之前先说下量词。

量词是为了简化正则表达式的读写而定义的,通用的形式是{m,n},这表示匹配的个数至少是m,最多是n,在','之后不能有空格,否则会出错,并且均为闭区间。

  • {n} 之前的元素必须出现n次
  • {m,n} 之前元素最少出现m次,最多n次
  • {m,} 之前的元素最少出现m次,无上限
  • {0,n} 之前的元素可以不出现,也可以出现,出现的话最多出现n次

除了之上,还有三个常用的量词*,?和+

  • * 等价于{0,}
  • + 等价于{1,}
  • \? 等价于{0,1}

还有^和$,分别表示段或者字符串的开始与结束。

import re
re.search("^travell?er$", "traveler")  # True
re.search("^travell?er$", "traveller")  # True
re.search("^ab\*", "abbbbbbb")      # True,返回"abbbbbbb"
re.search("^ab\*?", "abbbbbbb")     # True,返回"a"
re.search("^ab+", "abbbbbbb")      # True,返回"abbbbbbb"
re.search("^ab+?", "abbbbbbb")      # True,返回"ab"

对于一些预定义的字符集可以使用转义码可以更加紧凑的表示,re可以识别的转义码有3对,6个,分别为三个字母的大小写,他们的意义是相反的。

  • \d : 一个数字
  • \D : 一个非数字
  • \w : 字母或者数字
  • \W : 非字母,非数字
  • \s : 空白符(制表符,空格,换行符等)
  • \S : 非空白符

如果想指定匹配的内容在文本的相对位置,可以使用锚定,跟转义码类似。

  • ^ 字符或行的开始
  • $ 字符或行的结束
  • \A 字符串的开始
  • \Z 字符串结束
  • \b 一个单词开头或者末尾的空串
  • \B 不在一个单词开头或末尾的空串
import re
the_str = "This is some text -- with punctuation"
re.search(r'^\w+', the_str).group(0)    # This
re.search(r'\A\w+', the_str).group(0)   # This
re.search(r'\w+\S*$', the_str).group(0)  # punctuation
re.search(r'\w+\S*\Z', the_str).group(0)  # punctuation
re.search(r'\w*t\W*', the_str).group(0)  # text --
re.search(r'\bt\w+', the_str).group(0)   # text
re.search(r'\Bt*\B', the_str).group(0)   # 没有匹配

用组来解析匹配,简单的说就是在一个正则表达式中有几个小括号()将匹配的表达式分成不同的组,使用group()函数来获取某个组的匹配,其中0为整个正则表达式所匹配的内容,后面从1开始从左往右依次获取每个组的匹配,即每个小括号中的匹配。使用groups()可以获取所有的匹配内容。

import re
the_str = "--aabb123bbaa"
pattern = r'(\W+)([a-z]+)(\d+)(\D+)'
match = re.search(pattern, the_str)
match.groups()  # ('--', 'aabb', '123', 'bbaa')
match.group(0)  # '--aabb123bbaa'
match.group(1)  # '--'
match.group(2)  # 'aabb'
match.group(3)  # '123'
match.group(4)  # 'bbaa'

python对分组的语法做了扩展,我们可以对每个分组进行命名,这样便可以使用名称来调用。语法:(?P<name>pattern),使用groupdict()可以返回一个包含了组名的字典。

import re
the_str = "--aabb123bbaa"
pattern = r'(?P<not_al_and_num>\W+)(?P<al>[a-z]+)(?P<num>\d+)(?P<not_num>\D+)'
match = re.search(pattern, the_str)
match.groups()  # ('--', 'aabb', '123', 'bbaa')
match.groupdict() # {'not_al_and_num': '--', 'not_num': 'bbaa', 'num': '123', 'al': 'aabb'}
match.group(0)          # '--aabb123bbaa'
match.group(1)          # '--'
match.group(2)          # 'aabb'
match.group(3)          # '123'
match.group(4)          # 'bbaa'
match.group('not_al_and_num')  # '--'
match.group('al')         # 'aabb'
match.group('num')        # '123' '
match.group('not_num')      # 'bbaa'

以上的group()方法在使用的时候需要注意,只有在有匹配的时候才会正常运行,否则会抛错,所以在不能保证有匹配而又要输出匹配结果的时候,必须做校验。

在re中可以设置不通的标志,也就是search()和compile()等中都包含的缺省变量flag。使用标志可以进行完成一些特殊的要求,如忽略大小写,多行搜索等。

import re
the_str = "this Text"
re.findall(r'\bt\w+', the_str)  # ['this']
re.findall(r'\bt\w+', the_str, re.IGNORECASE) # ['this', 'Text']
(0)

相关推荐

  • Python正则表达式的七个使用范例详解

    作为一个概念而言,正则表达式对于Python来说并不是独有的.但是,Python中的正则表达式在实际使用过程中还是有一些细小的差别. 本文是一系列关于Python正则表达式文章的其中一部分.在这个系列的第一篇文章中,我们将重点讨论如何使用Python中的正则表达式并突出Python中一些独有的特性. 我们将介绍Python中对字符串进行搜索和查找的一些方法.然后我们讲讨论如何使用分组来处理我们查找到的匹配对象的子项. 我们有兴趣使用的Python中正则表达式的模块通常叫做're'. >>>

  • 基于Python正则表达式提取搜索结果中的站点地址

    正则表达式对于Python来说并不是独有的,最近在把google搜索的结果中所有的站点地址导出,于是想到用python正则表达式提取搜索结果中的站点地址. 这其中涉及几个需要解决的问题: 1.获取搜索的结果文本 为了获得更多的地址,我使用了Google的高级搜索功能,每个页面显示100条结果. 获得显示的结果后,可以查看源码,并保持成文本文件就有了搜索的结果文本 2.分析如何提取站点信息 首先需要分析获取的页面,查看以怎样的方式可以提取出站点信息. 我使用IE8自带的开发工具(按F12就会弹出来

  • Python 正则表达式(转义问题)

    先说一个比较囧的事情:在写虾米音乐试听下载器的时候遇到一个问题,因为保存的文件都是用音乐的标题命名的,所以碰到一些诸如「対峙/out border」等含有非法字符(哼哼,说的就是你 →_→ Windows)的标题的时候,就会保存失败.于是我想起了迅雷的解决方法:把所有的非法字符替换成下划线. 于是就引入了正则表达式的使用.一番搜索囫囵吞枣后,我写下了这样的函数: 复制代码 代码如下: def sanitize_filename(filename): return re.sub('[\/:*?<>

  • Python正则表达式操作指南

    Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式.Python 1.5之前版本则是通过 regex 模块提供 Emacs 风格的模式.Emacs 风格模式可读性稍差些,而且功能也不强,因此编写新代码时尽量不要再使用 regex 模块,当然偶尔你还是可能在老代码里发现其踪影. 1. 正则表达式基础 1.1. 简单介绍 正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方

  • Python入门篇之正则表达式

    正则表达式有两种基本的操作,分别是匹配和替换. 匹配就是在一个文本字符串中搜索匹配一特殊表达式: 替换就是在一个字符串中查找并替换匹配一特殊表达式的字符串.   1.基本元素   正则表达式定义了一系列的特殊字符元素以执行匹配动作. 正则表达式基本字符 字符 描述 text 匹配text字符串 . 匹配除换行符之外的任意一个单个字符 ^ 匹配一个字符串的开头 $ 匹配一个字符串的末尾 在正则表达式中,我们还可用匹配限定符来约束匹配的次数.   匹配限定符 最大匹配 最小匹配 描述 * * 重复匹

  • Python中正则表达式match()、search()函数及match()和search()的区别详解

    match()和search()都是python中的正则匹配函数,那这两个函数有何区别呢? match()函数只检测RE是不是在string的开始位置匹配, search()会扫描整个string查找匹配, 也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none 例如: #! /usr/bin/env python # -*- coding=utf-8 -*- import re text = 'pythontab' m = re.ma

  • python正则表达式中的括号匹配问题

    问题: m = re.findall('[0-9]*4[0-9]*', '[4]') 可以匹配到4. m = re.findall('([0-9])*4([0-9])*', '[4]') 匹配不到4. 这是为什么呢?PS,这个是一个简化的说明,我要用的正则比这个复杂,所以要用到(),表示一个序列的匹配. 补充一点,我放在notepad++中用的时候,两种写法都能匹配出来,不知道为什么python中就不行了. 答案: python的正则中用()会进行匹配,所以返回结果是['',''],就是两个()

  • 零基础写python爬虫之神器正则表达式

    接下来准备用糗百做一个爬虫的小例子. 但是在这之前,先详细的整理一下Python中的正则表达式的相关内容. 正则表达式在Python爬虫中的作用就像是老师点名时用的花名册一样,是必不可少的神兵利器. 一. 正则表达式基础 1.1.概念介绍 正则表达式是用于处理字符串的强大工具,它并不是Python的一部分. 其他编程语言中也有正则表达式的概念,区别只在于不同的编程语言实现支持的语法数量不同. 它拥有自己独特的语法以及一个独立的处理引擎,在提供了正则表达式的语言里,正则表达式的语法都是一样的. 下

  • python 正则表达式学习小结

    在Python中实现正则的方式是通过re(regular expression的缩写)模块来实现的,你可以调用re模块的各种方法来实现不同的功能,下面我们就来说下,在Python中通过re模块可以调用那些方法,以及这些方法的作用都是什么:还有就是正则的实例以及各种特殊符号的含义: 1.re.sub和replace: sub的全拼是substitute,也就是替换的意思:既然知道是替换了,那就很容易用到实例中了,其实replace也是替换的意思,只不过它们的用法不太相同,下面用一个例子来详细说明下

  • Python爬虫正则表达式常用符号和方法

    正则表达式并不是Python的一部分.正则表达式是用于处理字符串的强大工具,拥有自己独特的语法以及一个独立的处理引擎,效率上可能不如str自带的方法,但功能十分强大.得益于这一点,在提供了正则表达式的语言里,正则表达式的语法都是一样的,区别只在于不同的编程语言实现支持的语法数量不同:但不用担心,不被支持的语法通常是不常用的部分. 1.常用符号 . :匹配任意字符,换行符 \n 除外 :匹配前一个字符0次或无限次 ? :匹配前一个字符0次或1次 .* :贪心算法,尽可能的匹配多的字符 .*? :非

  • python正则表达式match和search用法实例

    本文实例讲述了python正则表达式match和search用法.分享给大家供大家参考.具体分析如下: python提供了2中主要的正则表达式操作:re.match 和 re.search. match :只从字符串的开始与正则表达式匹配,匹配成功返回matchobject,否则返回none: search :将字符串的所有字串尝试与正则表达式匹配,如果所有的字串都没有匹配成功,返回none,否则返回matchobject:(re.search相当于perl中的默认行为) import re d

  • Python中正则表达式的用法实例汇总

    正则表达式是Python程序设计中非常实用的功能,本文就常用的正则表达式做一汇总,供大家参考之用.具体如下: 一.字符串替换 1.替换所有匹配的子串 用newstring替换subject中所有与正则表达式regex匹配的子串 result, number = re.subn(regex, newstring, subject) 2.替换所有匹配的子串(使用正则表达式对象) reobj = re.compile(regex) result, number = reobj.subn(newstri

  • Python正则表达式匹配ip地址实例

    本文实例讲述了正则表达式匹配ip地址实例.代码结构非常简单易懂.分享给大家供大家参考. 主要实现代码如下: import re reip = re.compile(r'(?<![\.\d])(?:\d{1,3}\.){3}\d{1,3}(?![\.\d])') for ip in reip.findall(line): print "ip>>>", ip PS:关于正则,这里再为大家推荐2款非常方便的正则表达式工具供大家参考使用: JavaScript正则表达式

  • python3爬虫之入门基础和正则表达式

    前面的python3入门系列基本上也对python入了门,从这章起就开始介绍下python的爬虫教程,拿出来给大家分享:爬虫说的简单,就是去抓取网路的数据进行分析处理:这章主要入门,了解几个爬虫的小测试,以及对爬虫用到的工具介绍,比如集合,队列,正则表达式: 用python抓取指定页面: 代码如下: import urllib.request url= "http://www.baidu.com" data = urllib.request.urlopen(url).read()# d

随机推荐