re.findall()与它的发现不匹配

时间:2015-12-30 16:14:40

标签: python regex string

我有一个文本文件,其中包含以下行:

<pattern number=1 theme=pseudo>
<pattern number=2 theme=foo>
<pattern number=3 theme=bar>

我正在选择一个具有此功能的随机行:

def find_random_pattern(theme):
    found_lines = []
    pattern = open('poempatterns.txt','r')
    for line in pattern:
        found = re.findall("theme="+theme,line)
        for match in found:
            found_lines.append(line)

    selectedline = random.choice(found_lines)
    return selectedline

让我们说它返回了<pattern number=1 theme=pseudo>

当我使用此条件检查时,它会返回False

if find_random_pattern("pseudo") == "<pattern number=1 theme=pseudo>":
    return True
else:
    return False

为什么这两个字符串不匹配?

2 个答案:

答案 0 :(得分:4)

您期望>>> line = "<pattern number=1 theme=pseudo>" >>> import re >>> re.findall("theme=pseudo", line) ['theme=pseudo'] 返回整行但返回匹配的部分:

>>> re.findall(".*theme=pseudo.*", line)
['<pattern number=1 theme=pseudo>']

我建议你使用一个匹配整行的模式,例如:

def find_random_pattern(theme):
    found_lines = []
    pattern = open('poempatterns.txt','r')
    for line in pattern:
        # Call strip() just in case you have some blank spaces or \n at the end
        found = re.findall(".*theme=%s.*" % theme, line.strip())
        for match in found:
            found_lines.append(line)

    selectedline = random.choice(found_lines)
    return selectedline

您的最终代码如下:

import random
import re
import string

def find_random_pattern(theme):
    lines = open('poempatterns.txt','r').readlines()
    stripped_lines = map(string.strip, lines)
    found_lines = filter(lambda l: re.match(".*theme=%s.*" % theme, l), stripped_lines)
    return random.choice(found_lines)

更简洁的解决方案是:

{{1}}

答案 1 :(得分:1)

re.findall确实只返回匹配而不是整个line。 引自Python Docs.

  

re.findall(pattern,string,flags = 0)返回所有非重叠   字符串中的模式匹配,作为字符串列表。字符串是   从左到右扫描,并按找到的顺序返回匹配。如果   模式中存在一个或多个组,返回列表   组;如果模式有多个,这将是一个元组列表   组。结果中包含空匹配,除非他们触摸了   另一场比赛的开始。

<强>样本:

>>> s = 'Good morning Gotham!'
>>> re.findall('Go', s)
['Go', 'Go']

据说,如果您要求themeline退出,那么您实际上不需要regex

def find_random_pattern(theme):
    with open('poempatterns.txt','r') as pattern:
        found_lines = [line for line in pattern if theme in line]
    selectedline = random.choice(found_lines)
    return selectedline