【问题标题】:How to pass an argument for regex repetitions (python)如何为正则表达式重复传递参数(python)
【发布时间】:2018-03-20 20:39:18
【问题描述】:

我正在学习正则表达式。如果我想在一个字符串中找到所有 5 个字母的单词,我可以使用:

import re
text = 'The quick brown fox jumps over the lazy dog.'
print(re.findall(r"\b[a-zA-z]{5}\b", text))

但我想写一个简单的函数,它的参数包括字符串和找到的单词的长度。我试过这个:

import re
def findwords(text, n):
    return re.findall(r"\b[a-zA-z]{n}\b", text)    

print(findwords('The quick brown fox jumps over the lazy dog.', 5))

但这会返回一个空列表。 n 未被识别。

如何指定重复次数(或者在本例中为单词的长度)的参数?

【问题讨论】:

标签: python regex repeat


【解决方案1】:

Python 不会神奇地将n 的值填充到字符串中。为此,您需要使用format:

r"\b[a-zA-z]{{{}}}\b".format(n)

或者,如果您运行的是 Python >= 3.6,请使用新的 f-strings(可以与表示原始字符串的 r 前缀组合):

fr"\b[a-zA-z]{{{n}}}\b"

在这两种情况下,您都需要外部两个 {{}} 来创建文字 {},而内部是格式占位符。

如果您想避免转义文字 {},您可以使用较旧的 % 格式来实现相同的目的。对于这个n 需要始终是一个整数(它在这里):

r"\b[a-zA-z]{%i}\b" % n

【讨论】:

  • 这解释了很多。我现在知道如何使用 fr。但是使用 6 个括号是否足够干净?这是您在专业编程中看到的吗?
  • @Christy 是的,我想是的。在这种情况下,总是可以选择使用% 格式,不过:r"\b[a-zA-z]{%i}\b" % n
【解决方案2】:

它比您想象的要简单。 “正则表达式字符串”没有什么特别之处:它是一个简单、基本的日常文本字符串。唯一值得注意的是它通常r前缀定义,因为反斜杠在(无前缀的)Python字符串中也有一些含义,你不想把它们加倍, 和 ... 它按原样输入 Python 的内部正则表达式模块。

所以字符串的来源并不重要!以您喜欢的方式构建它,然后将结果输入re.findall

def findwords(text, n):
    return re.findall(r"\b[a-zA-z]{" +str(n) + r"}\b", text)

>>> findwords(text, 3)
['The', 'fox', 'the', 'dog']
>>> findwords(text, 4)
['over', 'lazy']

注意r 的重复使用,因为它不是正则表达式的特性,而是 Python 的特性,您需要在 all 单独的字符串前面加上它,以防止反斜杠泛滥并弄乱您的精心构造的表达式。

(此函数的输入也是如此。这也将起作用,除非您测试参数并拒绝非数字:

>>> findwords(text, '5} {1')
['quick ', 'brown ', 'jumps ']

...我没有。)

【讨论】:

  • 仍在努力理解;如果 n 代表一个长度,为什么要把它变成一个字符串?
  • @Christy 因为"a" + 5没有在Python中定义,而"a" + str(5) == "a5"
  • @Christy:不要忘记正则表达式参数仍然是一个字符串。里面没有“数字”。正则表达式解析器负责识别任何数字,而不是 Python。
【解决方案3】:

这可以很容易地完成,而无需生成正则表达式模式。只需简单地提取所有单词,然后使用列表理解来收集长度为 n 的所有单词。

See code in use here

import re

text = 'The quick brown fox jumps over the lazy dog.'
words = re.findall(r"[a-zA-Z]+", text)

print([w for w in words if len(w) == 3])

结果:['The', 'fox', 'the', 'dog']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-10
    • 2013-03-28
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多