zoukankan      html  css  js  c++  java
  • python 正则表达式Re

    Python正则表达式指南这篇文章很好,推荐阅读。
    本文则是简单记录下我自己学习Re的笔记, 环境是python3.5。


    ### 1.简单的Re语法 * `^` 匹配字符串开始位置。 * `$` 匹配字符串结束位置。 * `` 匹配一个单词边界。 * `d` 匹配一个数字。 * `D` 匹配一个任意的非数字字符。 * `x?` 匹配可选的 x 字符。换句话说,就是 0 个或者 1 个 x 字符。但是?还有第二个含义,作为正则的懒惰模式。 * `x*` 匹配 0 个或更多的 x。 * `x+` 匹配 1 个或者更多 x。 * `x{n,m}` 匹配 n 到 m 个 x,至少 n 个,不能超过 m 个。 * `x{n}`匹配n个x,一定是n个 * `(a|b|c)` 匹配单独的任意一个 a 或者 b 或者 c。 * `(x)` 这是一个组,它会记忆它匹配到的字符串。 * `w` 一个字母或数字 * `.` 任意字符 * `s` 空格 * `[]` 表示范围,[0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线。 * `[^]` 作为方括号中的第一个字符, `^`有特别的含义:非。 `[^abc]` 的意思是: “ 除了 a、 b 或 c之外的任何字符”。 ``` >>> re.search('[^aeiou]y$', 'vacancy') <_sre.SRE_Match object; span=(5, 7), match='cy'> >>> re.search('[^aeiou]y$', 'boy') >>> ```

    2.自然字符串

    如果你想要指示某些不需要如转义符那样的特别处理的字符串,那么你需要指定一个自然字符串。自然字符串通过给字符串加上前缀r或R来指定。例如r"Newlines are indicatedby "。
    一定要用自然字符串处理正则表达式。否则会需要使用很多的反斜杠。例如,后向引用符可以写成'1'或r'1'。
    强烈建议使用 Python 的 r 前缀,就不用考虑转义的问题了


    ### 3.re.search(pattern, string, flags=0) 和 re.match(pattern, string, flags=0) `search()`的帮助信息:`Scan through string looking for a match to the pattern, returning a match object, or None if no match was found.`。`match()`的帮助信息:`Try to apply the pattern at the start of the string, returning a match object, or None if no match was found.`。

    re 模块最基本的方法是 search()函数(类似于match()函数)。它使用正则表达式来匹配字符串( M)。如果成功匹配, search()返回一个匹配对象。

    >>> pattern = '^M?M?M?$'
    >>> re.search(pattern, 'M')
    <_sre.SRE_Match object; span=(0, 1), match='M'>
    

    match()函数同样的功能。

    >>> pattern = '^M?M?M?$'
    >>> re.match(pattern, 'M')
    <_sre.SRE_Match object; span=(0, 1), match='M'>
    

    re.match()只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search()匹配整个字符串,直到找到一个匹配。

    #!/usr/bin/python
    import re
    line = "Cats are smarter than dogs";
    
    matchObj = re.match( r'dogs', line, re.M|re.I)
    if matchObj:
       print("match --> matchObj.group() : ", matchObj.group())
    else:
       print("No match!!")
       
    matchObj = re.search( r'dogs', line, re.M|re.I)
    if matchObj:
       print("search --> matchObj.group() : ", matchObj.group())
    else:
       print("No match!!")
       
    # No match!!
    # search --> matchObj.group() :  dogs
    # [Finished in 0.1s]  
    

    ### 4.re.compile(pattern, flags=0) `Compile a regular expression pattern, returning a pattern object.` Re模块的`compile()`方法编译正则表达式,返回一个pattern对象。 编译后生成的 pattern 对象,已经包含了正则表达式(regular expression),所以调用对应的方法时不用给出正则表达式了。 用编译后的pattern对象去匹配字符串`patternobj.search(string)`,如果匹配成功,返回的结果调用`groups()`方法,可以得到这个正则表达式中定义的所有分组结果组成的元组。 但如果`search()`方法匹配不成功,返回`None`,它没有 `groups()`方法,所以调用 None.groups()将会抛出一个异常。 ``` >>> phonePattern = re.compile(r'^(d{3})-(d{3})-(d{4})$')

    dir(phonePattern)
    ['class', 'copy', 'deepcopy', 'delattr', 'dir', 'doc', 'eq', 'format', 'ge', 'getattribute', 'gt', 'hash', 'init', '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']

    phonePattern
    re.compile('^(d{3})-(d{3})-(d{4})$')

    m = phonePattern.search('800-555-1212')
    m
    <_sre.SRE_Match object; span=(0, 12), match='800-555-1212'>

    m.groups()
    ('800', '555', '1212')

    匹配失败

    phonePattern.search('800-555-1212-1234').groups()
    Traceback (most recent call last):
    File "<pyshell#24>", line 1, in
    phonePattern.search('800-555-1212-1234').groups()
    AttributeError: 'NoneType' object has no attribute 'groups'

    <br/>
    ### 5. re.sub(pattern, repl, string, count=0, flags=0)
    
    Return the string obtained by replacing the leftmost
    non-overlapping occurrences of the pattern in string by the
    replacement repl.  repl can be either a string or a callable;
    if a string, backslash escapes in it are processed.  If it is
    a callable, it's passed the match object and must return
    a replacement string to be used.
    
    正则表达式模块的`re.sub()`函数可以做字符串替换,如下它在字符串 s 中用正则表达式‘ROAD$’来搜索并替换成‘RD.’。
    

    s = '100 NORTH BROAD ROAD'
    import re
    re.sub('ROAD$', 'RD.', s)
    '100 NORTH BROAD RD.'

    re.sub('[abc]', 'o', 'caps')
    'oops'

    可能会认为该函数会将 caps 转换为 oaps,但实际上并不是这样。`re.sub()` 替换所有的匹配项,而不仅仅是第一个匹配项。因此该正则表达式将 caps 转换为 oops,因为无论是 c 还是 a 均被转换为 o 。
    在替换字符串中,用到了新的语法: 1,它表示“嘿,记住的第一个分组呢?把它放到这里。 ”在此例中, 记住了 y 之前的 c ,在进行替换时,将用 c 替代 c,用 ies 替代 y 。(如果有超过一个的记忆分组,可以使用 2 和 3 等等。)
    

    re.sub('([^aeiou])y$', r'1ies', 'vacancy')
    'vacancies'

    <br/>
    ### 6. re.findall(pattern, string, flags=0)
    
    Return a list of all non-overlapping matches in the string.
    
    If one or more capturing groups are present in the pattern, return
    a list of groups; this will be a list of tuples if the pattern
    has more than one group.
    
    Empty matches are included in the result.
    
    `re.findall()`接受一个正则表达式和一个字符串作为参数,然后找出字符串中出现该模式的所有地方。在这个例子里,模式匹配的是数字序列。`findall()`函数返回所有匹配该模式的子字符串的列表。
    

    re.findall('[0-9]+', '16 2-by-4s in rows of 8')
    ['16', '2', '4', '8']

    这里正则表达式匹配的是字母序列。再一次,返回值是一个列表,其中的每一个元素是匹配该正则表达式的字符串。
    

    re.findall('[A-Z]+', 'SEND + MORE == MONEY')
    ['SEND', 'MORE', 'MONEY']

    **懒惰模式和贪婪模式**
    `.*`具有贪婪的性质,首先匹配到不能匹配为止,根据后面的正则表达式,会进行回溯。
    `.*?`则相反,一个匹配以后,就往下进行,所以不会进行回溯,具有最小匹配的性质。
    `?`的一个用法是匹配0次或1次。但是`?`还有第二个含义,作为正则的懒惰模式。后边多一个`?`表示懒惰模式,必须跟在`*`或者`+`后边用。
    re 正则有两种模式,一种为贪婪模式(默认),另外一种为懒惰模式,以下为例:
    `(abc)dfe(gh)`
    对上面这个字符串使用`(.*)`将会匹配整个字符串,因为正则默认是尽可能多的匹配。
    虽然`(abc)`满足我们的表达式,但是`(abc)dfe(gh)`也同样满足,所以正则会匹配多的那个。
    如果我们只想匹配`(abc)`和`(gh)`就需要用到以下的表达式`(.*?)`
    
    惰性模式匹配示例:
    

    re.findall(' s.*? s', "The sixth sick sheikh's sixth sheep's sick.")
    [' sixth s', " sheikh's s", " sheep's s"]

    re.findall(' s.* s', "The sixth sick sheikh's sixth sheep's sick.")
    [" sixth sick sheikh's sixth sheep's s"]

    加上分组:
    

    re.findall(' s(.*?) s', "The sixth sick sheikh's sixth sheep's sick.")
    ['ixth', "heikh's", "heep's"]

  • 相关阅读:
    创意工坊pkg食用
    wordpress添加备案号出现乱码
    「Azure」数据分析师有理由爱Azure之四-Azure SQL的实操
    「Azure」数据分析师有理由爱Azure之三-对照Sqlserver学Azure
    「Azure」数据分析师有理由爱Azure之二-立即申请帐号开始学习之旅
    「Azure」数据分析师有理由爱Azure之一-Azure能带给我们什么?
    「Sqlserver」数据分析师有理由爱Sqlserver之十-Sqlserver自动化篇
    「Sqlserver」数据分析师有理由爱Sqlserver之九-无利益关系推荐Sqlserver书单
    「Sqlserver」数据分析师有理由爱Sqlserver之八-最刚需的数据导入导出功能-导出篇
    「Sqlserver」数据分析师有理由爱Sqlserver之七-最刚需的数据导入导出功能-导入篇
  • 原文地址:https://www.cnblogs.com/elie/p/6642446.html
Copyright © 2011-2022 走看看