Python Regex将字符串作为模式匹配并返回数字

时间:2011-06-16 19:49:47

标签: python regex substring match

我有一些代表文本文件中某些数据的行。它们都是以下格式:

s = 'TheBears      SUCCESS Number of wins : 14'

它们都以名称开头,然后是空格和文本'SUCCESS胜算数:',最后是胜利数n1。有多个字符串,每个字符串具有不同的名称和值。我正在尝试编写一个程序,可以解析任何这些字符串并返回数据集的名称和字符串末尾的数值。我试图使用正则表达式来做到这一点,我想出了以下内容:

import re
def winnumbers(s):
    pattern = re.compile(r"""(?P<name>.*?)     #starting name
                             \s*SUCCESS        #whitespace and success
                             \s*Number\s*of\s*wins  #whitespace and strings
                             \s*\:\s*(?P<n1>.*?)""",re.VERBOSE)
    match = pattern.match(s)

    name = match.group("name")
    n1 = match.group("n1")

    return (name, n1)

到目前为止,我的程序可以返回名称,但问题出现之后。他们都有文字“SUCCESS胜利数量:”所以我的想法是找到一种方法来匹配这个文本。但我意识到我的匹配精确子字符串的方法现在不正确。有没有办法将整个子串匹配作为模式的一部分?我最近一直在阅读正则表达式,但没有找到这样的东西。我仍然是编程的新手,我很感激任何帮助。

最后,我将使用float()将n1作为一个数字返回,但是我把它留下了,因为它现在没有正确找到数字,只会返回错误。

3 个答案:

答案 0 :(得分:2)

试试这个:

((\S+)\s+SUCCESS Number of wins : (\d+))

结果如下:

>>> regex = re.compile("((\S+)\s+SUCCESS Number of wins : (\d+))")
>>> r = regex.search(string)
>>> r
<_sre.SRE_Match object at 0xc827cf478a56b350>
>>> regex.match(string)
<_sre.SRE_Match object at 0xc827cf478a56b228>

# List the groups found
>>> r.groups()
(u'TheBears SUCCESS Number of wins : 14', u'TheBears', u'14')

# List the named dictionary objects found
>>> r.groupdict()
{}

# Run findall
>>> regex.findall(string)
[(u'TheBears SUCCESS Number of wins : 14', u'TheBears', u'14')]
# So you can do this for the name and number:
>>> fullstring, name, number = r.groups()

如果您不需要完整的字符串,只需删除环绕括号。

答案 1 :(得分:2)

我认为这里没有实际需要使用正则表达式。因此,如果您可以接受以下代码,请使用以下代码(请注意,我已将其发布,因此您可以使用另一个选项):

dict((line[:line.lower().index('success')+1], line[line.lower().index('wins:') + 6:]) for line in text.split('\n') if 'success' in line.lower())

如果您确定所有单词都被单个空格拆分:

output={}
for line in text:
    if 'success' in line.lower():
        words = line.strip().split(' ')
        output[words[0]] = words[-1]

答案 2 :(得分:1)

如果中间的文本总是不变的,则不需要正则表达式。内置的字符串处理功能将更高效,更易于开发,调试和维护。在这种情况下,您可以使用内置的split()函数来获取碎片,然后根据需要清理这两个部分:

>>> def winnumber(s):
...     parts = s.split('SUCCESS Number of wins : ')
...     return (parts[0].strip(), int(parts[1]))
... 
>>> winnumber('TheBears      SUCCESS Number of wins : 14')
('TheBears', 14)

请注意,我已将输出的数量作为整数输出(可能这总是一个整数),但您可以轻松地将float() - 或任何其他转换函数 - 替换为int()如果你愿意的话。

编辑:显然这仅适用于单行 - 如果您使用多行调用该函数,则会给您带来错误。要处理整个文件,我会使用map()

>>> map(winnumber, open(filename, 'r'))
[('TheBears', 14), ('OtherTeam', 6)]

此外,我不确定您对此代码的最终用途,但您可能会发现使用输出作为字典更容易:

>>> dict(map(winnumber, open(filename, 'r')))
{'OtherTeam': 6, 'TheBears': 14}