我如何在Python中的regex中使用list作为变量

时间:2013-08-08 21:57:44

标签: python regex list

如何在regexp中使用list变量? 问题出在这里:

re.search(re.compile(''.format('|'.join(map(re.escape, kand))), corpus.raw(fileid)))

错误是

TypeError: unsupported operand type(s) for &: 'str' and 'int'

简单的re.search效果很好,但我需要list作为re.search中的第一个属性:

for fileid in corpus.fileids():
    if re.search(r'[Чч]естны[й|м|ого].труд(а|ом)', corpus.raw(fileid)):
        dict_features[fileid]['samoprezentacia'] = 1
    else:
        dict_features[fileid]['samoprezentacia'] = 0

if re.search(re.compile('\b(?:%s)\b'.format('|'.join(map(re.escape, kand))), corpus.raw(fileid))):
    dict_features[fileid]['up'] = 1
else:
    dict_features[fileid]['up'] = 0

返回dict_features

顺便说一句kand是列表:

kand = [line.strip() for line in open('kand.txt', encoding="utf8")]
输出kand中的

['apple', 'banana', 'peach', 'plum', 'pineapple', 'kiwi']

编辑:我在Windows 7上使用Python 3.3.2和WinPython 完整错误堆栈:

Traceback (most recent call last):
  File "F:/Python/NLTK packages/agit_classify.py", line 59, in <module>
    print (regexp_features(agit_corpus))
  File "F:/Python/NLTK packages/agit_classify.py", line 53, in regexp_features
    if re.search(re.compile(r'\b(?:{0})\b'.format('|'.join(map(re.escape, kandidats_all))), corpus.raw(fileid))):
  File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\re.py", line 214, in compile
    return _compile(pattern, flags)
  File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\re.py", line 281, in _compile
    p = sre_compile.compile(pattern, flags)
  File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\sre_compile.py", line 494, in compile
    p = sre_parse.parse(p, flags)
  File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\sre_parse.py", line 748, in parse
    p = _parse_sub(source, pattern, 0)
  File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\sre_parse.py", line 360, in _parse_sub
    itemsappend(_parse(source, state))
  File "F:\WinPython-32bit-3.3.2.0\python-3.3.2\lib\sre_parse.py", line 453, in _parse
    if state.flags & SRE_FLAG_VERBOSE:
TypeError: unsupported operand type(s) for &: 'str' and 'int'

2 个答案:

答案 0 :(得分:2)

您获得实际异常的原因是括号不匹配。让我们分解它以使其更清晰:

re.search(
    re.compile(
        ''.format('|'.join(map(re.escape, kand))), 
        corpus.raw(fileid)))

换句话说,您将一个字符串corpus.raw(fileid)作为re.compile的第二个参数传递,而不是re.search的第二个参数。

换句话说,你试图将它用作flags值,它应该是一个整数。当re.compile尝试使用字符串上的&运算符来测试每个标志位时,它会引发TypeError

如果你超过了这个错误,那么re.search本身会引发一个TypeError,因为你只传递一个参数而不是两个参数。

这正是您不应该编写过于复杂的表达式的原因。他们调试非常痛苦。如果你用不同的步骤写出来,那就很明显了:

escaped_kand = map(re.escape, kand)
alternation = '|'.join(escaped_kand)
whatever_this_was_supposed_to_do = ''.format(alternation)
regexpr = re.compile(whatever_this_was_supposed_to_do, corpus.raw(fileid))
re.search(regexpr)

这也很明显,首先你不需要做一半的工作。

首先,re.search采用模式,而不是编译的regexpr。如果它恰好与编译的regexpr一起工作,那只是一个意外。所以,表达的整个部分都是无用的。只是传递模式本身。

或者,如果您有充分的理由编译regexpr,正如re.compile所解释的那样,结果正则表达式对象“可用于使用其match()search()方法进行匹配” 。因此,请使用编译对象的search方法,而不是顶级re.search函数。

其次,我不知道你期望''.format(anything)做什么,但它除了''之外不可能返回任何内容。

答案 1 :(得分:1)

你正在混淆旧new string formatting rules。此外,您需要使用带有正则表达式的原始字符串,或\b表示backspace,而不是word boundary

'\b(?:%s)\b'.format('|'.join(map(re.escape, kand)))

应该是

r'\b(?:{0})\b'.format('|'.join(map(re.escape, kand)))

此外,请注意\b仅在您的“字词”以字母数字字符(或_)开头和结尾时才有效。