Python 将存储在变量中的正则表达式与量词组合的正确语法是什么?

Python 将存储在变量中的正则表达式与量词组合的正确语法是什么?,python,regex,Python,Regex,我知道关于在正则表达式中使用变量,堆栈溢出中已经有很多问题,如果变量是一个单词,或者只需要匹配一次,我就设法使它工作;然而,一旦我添加了一个特殊字符/空格和一个量词,我就无法使它匹配。例如,我想将某个变量中的任何内容与包含该变量的3个连续副本的任何字符串相匹配: import re some_var = "what what" should_match = "what what what what what what hey" not_a_match = "what what what wh

我知道关于在正则表达式中使用变量,堆栈溢出中已经有很多问题,如果变量是一个单词,或者只需要匹配一次,我就设法使它工作;然而,一旦我添加了一个特殊字符/空格和一个量词,我就无法使它匹配。例如,我想将某个变量中的任何内容与包含该变量的3个连续副本的任何字符串相匹配:

import re

some_var = "what what"

should_match = "what what what what what what hey"
not_a_match = "what what what what hey what what"

match = re.search(re.escape(some_var){3}, should_match)
no_match = re.search(re.escape(some_var){3}, not_a_match)
然而,最后两行给了我一个语法错误,我已经试过了

'(.*)'+re.escape(some_var){3}+'(.*)'
('(.*)'+re.escape(some_var)+'(.*)'){3}
'(.*)'+'re.escape(some_var){3}'+'(.*)'
're.escape(some_var){3}'

。。。我似乎无法获得它正确匹配的语法(我一直得到假条件)。我试着寻找答案,但我不知道如何让它正确识别量词

您需要将几个单词分组并添加可选的空白:

match = re.search(r"(?:\s*{0}){{3}}".format(re.escape(some_var)), should_match)

正则表达式看起来像
(?:\s*what\what){3}
,并且:它匹配3个

  • \s*
    -0或更多空格后跟
  • what\what
    -literal
    what
    子字符串

正则表达式模式只是字符串(任何非字母数字的反斜杠都被转义以匹配文字字符串),因此您可以使用
格式
%
运算符或串联来创建所需的模式字符串

给定
n
的某个值作为量词,在本例3中,您需要适当地构造正则表达式字符串。
{3}
部分需要紧跟在
re.escape(some_var)
之后的模式字符串中

您可以使用
%
运算符:

>>> n=3
>>> r'(?:\s*%s){%i}' % (re.escape(some_var), n)
'(?:\\s*what\\ what){3}'
或者,使用
格式

>>> r'(?:\s*{0}){{{1}}}'.format(re.escape(some_var), n)
'(?:\\s*what\\ what){3}'
或使用串联:

>>> r'(?:\s*'+re.escape(some_var)+'){'+str(n)+'}'
'(?:\\s*what\\ what){3}'
这些字符串中的任何一个现在都将按照您的想法工作:

>>> re.match(r'(?:\s*%s){%i}' % (re.escape(some_var), n), should_match)
<_sre.SRE_Match object at 0x104244b28>
>>> re.match(r'(?:\s*%s){%i}' % (re.escape(some_var), n), not_a_match)
>>> 
重新匹配(r'(?:\s*%s){%i}'(重新转义(某些变量),n),应该匹配) >>>re.match(r'(?:\s*%s){%i}'(re.escape(一些变量),n),而不是一个匹配) >>>
使用如下字符串连接来构造它:
(.*)(?:'+re.escape(some_var)+'{3}(.*)
换句话说,正则表达式部分是实际的字符串部分。但是,如果以这种方式同时执行,则可能会遇到边缘问题。它太长,无法解释,但如果您希望空格分隔,它必须有一个开始和一个结束,即,
some_var(?:\s+some_var){2}
,否则,您将追尾。@sln您可以提供一个我可以测试/处理的示例边缘情况吗?正则表达式对我来说还是很新的,所以我仍然在消化(?…)语法,我无法想出一个边缘案例来测试。非常感谢。问题在于
3个连续副本的前提。要有任何东西的3个副本,中间有2个无边界边界。这意味着
应该匹配=“what-what-what-what-what”
。因为在你们看来,空格是看不见的,你们认为它应该匹配,但所有的文本都是二进制代码,占用内存中的实字节。通常,如果您希望允许不同的分隔符边界,那么它会像我发布的那样完成。这是为了一致性
(?:\s*some_var){3}
是一种黑客攻击,特别是为了匹配您的不一致问题。在现实世界中,不是这样做的。存在一个边缘条件问题。谢谢!这个问题困扰了我好几个小时了!谢谢你提供关于它如何工作的信息,否则这肯定是我的下一个问题:)不客气。我只想补充一点,如果您想提取值,可以使用
match.group().strip()
来去除任何“随意”的前导空格。@Melissa:很高兴它对您有用。如果我的答案对你有帮助(请参阅),请考虑一下,如果你现在有这个特权。“SrbIZHEV完成和完成:”对于<代码>匹配。GROUP()。我意识到我连接不正确。似乎我主要缺少(?:)语法(我尝试了.format()和%formatting,但在编写正则表达式时仍然出现语法错误)