无法将值传入 re.findall(Python)
有人能帮我理解为什么这个能工作吗...
z = re.findall(r'(foobar)', string)
但是这个却不行?
regexStr = "r'(foobar)'"
z = re.findall(regexStr, string)
我打印了regexStr,发现它的输出和r'(foobar)'完全一样。
有人能帮帮我吗?我也试过把单引号转义。
JD
3 个回答
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
想了解更多信息:
字符串前面的“r”这个标记应该放在引号外面。
regexStr = r'(foobar)'
根据文档的说明,“字符串字面量可以选择性地在前面加上一个字母'r'或'R';这样的字符串被称为原始字符串,它们在处理反斜杠转义序列时有不同的规则。”
解决你问题的方法是
regexStr = r'(%s)' % searchString
在这里,searchString会替换掉%s
在Python中,使用这种方式通常比简单的拼接字符串要好(也就是 str1 + str2 + ... 这种方式)。
特别是这样做的时候,你不需要担心把整数、浮点数等转换成字符串。
关于这个主题的更多内容可以在这里找到:3.5. 格式化字符串
r不应该是字符串的一部分,它只是告诉Python解释器这是什么类型的字符串:
r('hello\n') # Raw string => (hello\n)
u'unicodestring'