理解Python中的're.search()'行为

时间:2015-01-31 08:55:17

标签: python regex python-2.7

这是我用来从一串字母数字中分割字母和数字的python代码:

input_string = 'abcdefghijklmnopqrstuvwxyz1234567890'
import re
print re.search('[a-z]*', input_string).group()
print re.search('[0-9]*', input_string).group()

在输出中我得到字母串但没有得到数字串。如果我修改代码如下,则输出显示数字:

print re.search('[0-9]*$', input_string).group()

我习惯grep,我发现它的功能类似于re模块的功能,如果我在shell中运行以下命令,我会得到所需的结果:

echo "abcdefghijklmnopqrstuvwxyz1234567890" | grep "[0-9]*"

我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:8)

我建议您使用re.findall函数(按顺序进行全局匹配)而不是re.search,因为re.search只会返回第一个匹配

>>> input_string = 'abcdefghijklmnopqrstuvwxyz1234567890'
>>> print re.findall(r'\d+|[a-z]+', input_string)
['abcdefghijklmnopqrstuvwxyz', '1234567890']

并且也不使用[a-z]*,它也会返回空字符串。 *将重复前一个令牌零次或多次,+将重复前一个令牌一次或多次。

>>> print re.search(r'\d+', input_string).group()
1234567890
>>> print re.search(r'[a-z]+', input_string).group()
abcdefghijklmnopqrstuvwxyz

为什么第一个在第二个失败时起作用?

>>> print re.search('[a-z]*', input_string).group()
abcdefghijklmnopqrstuvwxyz
>>> print re.search('[0-9]*', input_string).group()

>>>

*重复前一个标记零次或多次,即它将匹配每个不匹配字符之前存在的空字符串。第一个[a-z]*返回abcdefghijklmnopqrstuvwxyz,因为此子字符串位于开头。如果输入类似8abcdefghijklmnopqrstuvwxyz,则返回空字符串。此行为是因为re.search函数,它在找到第一个匹配后停止。这里8与上述正则表达式不匹配,正如我所说,[a-z]*正则表达式将匹配之前存在的空字符串8

regex = [0-9]*,string =“abcdefghijklmnopqrstuvwxyz1234567890”

找到第一场比赛后

re.search停止。此处a[0-9]不匹配,但[0-9]*a之前存在的空字符串匹配,因为*将重复前一个标记或多次。这就是为什么在第二种情况下你得到一个空字符串作为输出。

>>> print re.search('[0-9]*$', input_string).group()
1234567890

由于我们添加了行锚点的结尾,它将在行尾搜索零个或多个数字。如果它在最后找不到更多数字,它将返回一个空字符串作为匹配。

>>> print re.search('[0-9]*$', '12foo').group()

>>> 

答案 1 :(得分:1)

  

在输出中我得到了一串字母但没有得到   数字串。

我刚检查了ruby和perl,它们产生了相同的结果。

digit pattern匹配:

  1. 第一个字符和第二个字符之间的零宽度点。
  2. 第二个字符和第三个字符之间的零宽度点。
  3. 字符串末尾的数字序列。
  4. 但是,re.search()只返回第一个匹配。

    小写letter pattern匹配:

    1. 字符串开头的字母序列。
    2. 1和2之间的零宽度点。
    3. 2和3之间的零宽度点。
    4.   

      如果我在shell中运行以下命令,我会得到所需的结果:

      echo "abcdefghijklmnopqrstuvwxyz1234567890" | grep "[0-9]*"
      

      在bash shell中,我得到:

      $ echo "abcdefghijklmnopqrstuvwxyz1234567890" | grep "[0-9]*"
      abcdefghijk
      

      我用echo,grep和其他模式得到了类似的奇怪结果。

      对评论的回应:

      $ bash --version
      GNU bash, version 3.2.48(1)-release (x86_64-apple-darwin10.0)
      Copyright (C) 2007 Free Software Foundation, Inc.
      
      $ echo "abc123" | grep -o "[a-z]*"
      abc
      $ echo "abc123" | grep -o "[0-9]*"
      $ echo "abc123" | grep -o "[0-9]*$"
      123
      $