【问题标题】:How do i use list as variable in regexp in Python如何在 Python 的正则表达式中使用列表作为变量
【发布时间】:2013-08-08 21:57:44
【问题描述】:

如何在正则表达式中使用列表变量? 问题出在这里:

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

错误是

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

简单的 re.search 效果很好,但我需要列表作为 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'

【问题讨论】:

  • 您希望''.format 做什么?
  • 你为什么会做re.search(re.compile(…))?只需将正则表达式模式字符串传递给re.search 就可以完成完全相同的事情。或者,如果您需要显式编译正则表达式(例如,性能,因为您将重复使用它们,或者只是重构您的代码),只需在编译后使用 search 方法正则表达式。
  • 我假设格式列表为 apple|banana|peach - 我从 stackoverflow 上的另一个答案中复制了这个
  • 另外,我看不出你是怎么从那行代码中得到这个错误的。你能给我们完整的回溯,以及它所指的实际代码行吗?
  • 现在实验并意识到这是可行的,但不确定它是否正确或pythonic:re.search(re.compile('\b(?:%s)\b' + '|'.join (map(re.escape, kandidats_all))), corpus.raw(fileid))

标签: python regex list


【解决方案1】:

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

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

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

换句话说,您试图将其用作flags 值,它应该是一个整数。当re.compile 尝试在字符串上使用&amp; 运算符来测试每个标志位时,它会引发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 采用模式,而不是编译的正则表达式。如果它恰好与已编译的正则表达式一起工作,那只是一个意外。因此,表达式的整个部分是无用的。只需传递模式本身。

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

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

【讨论】:

    【解决方案2】:

    您正在混合 old 和 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 仅在您的“单词”以字母数字字符(或_)开头和结尾时才有效。

    【讨论】:

    • 现在进行实验并意识到这是可行的,但不确定它是否正确或pythonic:re.search(re.compile('\b(?:%s)\b' + '|'.join (map(re.escape, kandidats_all))), corpus.raw(fileid))
    • 为什么不...re.compile('\b(?:%s)\b' + '|'.join(map(re.escape, kandidats_all))).search(kandidats_all),那么你是从编译的正则表达式对象调用搜索
    猜你喜欢
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2015-10-05
    • 1970-01-01
    • 2017-10-11
    相关资源
    最近更新 更多