Python正则表达式实现字符串转义

时间:2020-03-05 18:40:12  来源:igfitidea点击:

我正在尝试使用Python正则表达式和反向引用实现字符串转义,并且它似乎并不想很好地工作。我确定这是我做错的事情,但我不知道该怎么办...

>>> import re
>>> mystring = r"This is \n a test \r"
>>> p = re.compile( "\\(\S)" )
>>> p.sub( "\1", mystring )
'This is n a test r'
>>> p.sub( "\\\1", mystring )
'This is \n a test \r'
>>> p.sub( "\\1", mystring )
'This is \1 a test \1'

我想用\ [char]替换\ [char],但是Python中的反向引用似乎没有遵循我在使用过的所有其他实现中所遵循的相同规则。有人可以照亮吗?

解决方案

回答

好吧,我认为我们可能错过了r或者错误地计算了反斜杠...

"\n" == r"\n"

>>> import re
>>> mystring = r"This is \n a test \r"
>>> p = re.compile( r"[\][\](.)" )
>>> print p.sub( r"\", mystring )
This is \n a test \r
>>>

如果我了解的是所要求的。

我怀疑更常见的要求是这样的:

>>> d = {'n':'\n', 'r':'\r', 'f':'\f'}
>>> p = re.compile(r"[\]([nrfv])")
>>> print p.sub(lambda mo: d[mo.group(1)], mystring)
This is \
 a test \
>>>

有兴趣的学生还应该阅读Ken Thompson的《对信任的思考》,其中我们的英雄使用类似的示例来说明信任我们自己没有从机器代码中引导的编译器的危险。

回答

Python的结果字符串表示法给我们带来了欺骗。 Python表达式:

'This is \n a test \r'

代表字符串

This is \n a test \r

这是我想我们想要的。尝试在每个p.sub()调用之前添加" print",以打印返回的实际字符串,而不是该字符串的Python表示形式。

>>> mystring = r"This is \n a test \r"
>>> mystring
'This is \n a test \r'
>>> print mystring
This is \n a test \r

回答

我的想法是,我将读取一个转义的字符串,然后对其进行转义(Python明显缺乏的一项功能,首先我们不需要使用正则表达式)。不幸的是,我没有被反斜杠所欺骗...

另一个说明性示例:

>>> mystring = r"This is \n ridiculous"
>>> print mystring
This is \n ridiculous
>>> p = re.compile( r"\(\S)" )
>>> print p.sub( 'bloody', mystring )
This is bloody ridiculous
>>> print p.sub( r'', mystring )
This is n ridiculous
>>> print p.sub( r'\1', mystring )
This is  ridiculous
>>> print p.sub( r'\', mystring )
This is \n ridiculous

我想要打印的是

This is 
ridiculous

回答

那不是安德斯的第二个例子吗?

在2.5中,我们还可以应用string-escape编码:

>>> mystring = r"This is \n a test \r"
>>> mystring.decode('string-escape')
'This is \n a test \r'
>>> print mystring.decode('string-escape')
This is 
 a test 
>>>

回答

标记;他的第二个示例要求最初将每个转义的字符扔到数组中,如果转义序列不在数组中,则会生成KeyError。它会死于除提供的三个字符之外的任何其他字符(请尝试\ v尝试),并且每次要取消转义字符串(或者保留全局数组)时枚举每个可能的转义序列是一个非常糟糕的解决方案。与PHP类似,它使用带有lambda的preg_replace_callback()代替了preg_replace(),在这种情况下完全没有必要。

抱歉,如果我不喜欢它,我对Python感到非常沮丧。我使用过的所有其他正则表达式引擎都支持此功能,我不明白为什么这不起作用。

谢谢回复;我最初想要的是string.decode('string-escape')`函数。如果有人对正则表达式反向引用问题有一般的解决方案,请随时发布它,我也将其作为答案。