无法将值传入 re.findall(Python)

0 投票
3 回答
915 浏览
提问于 2025-04-16 20:18

有人能帮我理解为什么这个能工作吗...

z = re.findall(r'(foobar)', string)

但是这个却不行?

regexStr = "r'(foobar)'"
z = re.findall(regexStr, string)

我打印了regexStr,发现它的输出和r'(foobar)'完全一样。

有人能帮帮我吗?我也试过把单引号转义。

JD

3 个回答

0

r这个标记用来创建一个原始字符串。它告诉Python不要把反斜杠后面的特殊符号(比如\t代表制表符或\n代表换行符)转换成特殊字符。这个标记和正则表达式的转义规则没有关系。

>>> len('\t')  # tab character only
1
>>> len(r'\t') # backslach character followed by a tee
2

不过,正则表达式的语法有自己的一套转义规则,这些规则常常和Python内置字符串的转义规则冲突。使用r这个关键词可以让我们只处理一种情况。例如,下面的第一个字符串是一个匹配单词字符的正则表达式文本,第二个字符串也是,因为Python会把\\转换成\,除非你使用r关键词。

>>> re.compile(r'\w') == re.compile('\\w')
True

在你的例子中,r'(foobar)''(foobar)'是完全一样的,因为没有反斜杠需要转义。这个字符串在你脑海中是一个正则表达式文本r关键词并没有告诉Python以那样的方式来理解这个字符串。Python只知道正则表达式对象,这些对象是通过re.compile()来构建的,或者是通过像re.findall()这样的内置方法自动编译的。

编译正则表达式对象有自己的一套规则,这些规则和内置字符串的转义规则不同,正则表达式的规则和r关键词没有关系。正则表达式编译器并不理解r的特殊含义,只有Python解释器知道。

在你的例子中,"r'(foobar)'"中的r关键词没有特别的处理,因为它直接传递给了正则表达式编译器。你实际上是在构建一个正则表达式,它会搜索一个以"开头,接着是r,然后是其他内容的字符串。这就是为什么这两个表达式不同的原因。

>>> re.compile(r'(foobar)') == re.compile('"r(foobar)"') # your expressions
False

在这里使用r关键词没有任何影响:

>>> re.compile(r'(foobar)') == re.compile('(foobar)')
True
>>> re.compile(r'"r(foobar)"') == re.compile('"r(foobar)"')
True

想了解更多信息:

3

字符串前面的“r”这个标记应该放在引号外面。

regexStr = r'(foobar)'

根据文档的说明,“字符串字面量可以选择性地在前面加上一个字母'r'或'R';这样的字符串被称为原始字符串,它们在处理反斜杠转义序列时有不同的规则。”

0

解决你问题的方法是

regexStr = r'(%s)' % searchString

在这里,searchString会替换掉%s

在Python中,使用这种方式通常比简单的拼接字符串要好(也就是 str1 + str2 + ... 这种方式)。

特别是这样做的时候,你不需要担心把整数、浮点数等转换成字符串。

关于这个主题的更多内容可以在这里找到:3.5. 格式化字符串

r不应该是字符串的一部分,它只是告诉Python解释器这是什么类型的字符串:

r('hello\n')  # Raw string => (hello\n)
u'unicodestring'

撰写回答