搜索

首页  >  问答  >  正文

python中正则表达式*?的一个问题

1.看书上教材说*?是非贪婪模式,那么对于下面这段代码,为啥结果是空呢?

>>> import re
>>> line = 'cats are smart than dogs.'
>>> m=re.match(r'(.*?)',line)
>>> m.group()

结果为:''
为什么结果为空呢?不应该是cats么?难道字符串前默认有个空字符?
新手求明白人给解答下,谢谢了

PHP中文网PHP中文网2768 天前726

全部回复(4)我来回复

  • 大家讲道理

    大家讲道理2017-04-17 17:29:36

    . = 任意字符
    * = 出现 0 或多次,相当于 {0,}
    ? = 取前面匹配最少的,相当于 {0,1}

    综合起来就是“任意字符出现0次“,所以就是什么都没有。

    要匹配到 cats 应该利用 cats 后面的空格,r'(.*?) '

    回复
    0
  • 高洛峰

    高洛峰2017-04-17 17:29:36

    我个人理解的是,.*?匹配的是^ 就是开始的那个位置,正则表达式里面,位置也是可以被匹配的,比如:

    In [1]: s = 'a'
    In [2]: re.sub(r'^','b',s)
    Out[2]: 'ba'

    这个例子就是替换了^ , 同理 $也一样, 所以你的.*?直接匹配了^.
    PS: 在使用正则的时候,尤其是文本内容比较多的时候, 不建议使用.*而是[sS]* 或者[dD]*等等

    回复
    0
  • 高洛峰

    高洛峰2017-04-17 17:29:36

    这是正则表达式贪婪匹配和非贪婪匹配的区别:

    • 贪婪模式:在能匹配的时候,匹配最长的。表达式不以?结尾。

    • 非贪婪模式:在能匹配的时候,匹配最短的。表达式以?结尾。

    比如字符串abcabcabc,当我想要匹配以a开头、以c结尾的字符串时,存在三个匹配:abcabcabcabcabcabc,其中最长的abcabcabc可以用a.*c匹配,而最短的abc可以用a.*?c匹配。

    >>> import re
    >>> line = "abcabcabc"
    >>> m = re.match(r'a.*c', line)
    >>> m.group()
    'abcabcabc'
    >>> m = re.match(r'a.*?c', line)
    >>> m.group()
    'abc'

    为什么结果为空呢?不应该是cats么?

    因为.*是贪婪模式,会匹配最长的字符串,其中每个字符都是任意字符(.),即由所有输入字符组成的字符串。而.*?是非贪婪模式,会匹配最短的字符串,其中每个字符都是任意字符(.),即空字符串。

    如果想匹配 cats 这个单词,应该使用cats。如果想匹配输入字符串中的第一个单词,应该使用w+S+

    >>> m=re.match(r'\w+',line)
    >>> m.group()
    'cats'
    >>> m=re.match(r'\S+',line)
    >>> m.group()
    'cats'

    难道字符串前默认有个空字符?

    没有,不过在正则表达式中,可以用^表示字符串的开始位置,用$表示结束位置。注意这两个字符(^$)是匹配规则规定的符号,用于你所写的规则字符串,不是说待匹配字符串中包含这两个符号。

    回复
    0
  • 黄舟

    黄舟2017-04-17 17:29:36

    . 边界匹配,不消耗带匹配字符串中字符,又是非贪婪模式,所以匹配不到字符串

    回复
    0
  • 取消回复