我遇到的情况可能会遇到" {key"或" {key \ n"我想转换" {key \ n"到" {key"不影响" \ n"的其他实例在字符串中。 key可以包含a-z,A-Z,0-9,下划线,短划线中的任何一个。
我认为这会奏效,但它没有:
import re
test = '{sq-a_ foo}{sq-b_\nbar}\n{sq-c_ gluck}'
print re.sub(r'(\{*[_a-zA-Z0-9-]\n)','\1 ',test)
它返回:
{sq-a_ foo}{sq-b bar}
{sq-c_ gluck}
...有一个隐形字符0x01
,右下角应该是替换字符。
我期待这个:
{sq-a_ foo}{sq-b_ bar}
{sq-c_ gluck}
所以我的问题是,sq-b
之后的下划线在哪里? 0x01
来自哪里?
答案 0 :(得分:1)
首先,让我们看看你的原始表达:
\{*
匹配0个或更多文字{
。在这种情况下,因为它期望下一个字符是其中一个_a-zA-Z0-9-
后跟\n
,所以它会在\n
之前捕获 last 字符并且有效地使\{*
语句无关紧要。
然后,由于\n
与其他单个字符一起包含在您的捕获组中,因此当您使用\1
反向引号替换它时,换行符将与其他字符一起包含在替换中。在这种情况下,您需要用空格替换_\n
,这就是空间消失的原因。
这给我的答案包括下划线 - 如果你想替换换行符,你需要将它从捕获组中排除。另外,愚蠢的我,我错过了反向引用中缺少文字字符串r''
前缀:
import re
test = '{sq-a_ foo}{sq-b_\nbar}\n{sq-c_ gluck}'
print re.sub(r'(\{[^}]+)\n(.+\})',r'\1 \2',test)
输出:
{sq-a_ foo}{sq-b_ bar}
{sq-c_ gluck}
另外值得注意的是 - 您可以使用\w
代替a-zA-Z_
来表达您的表达方式;)
所有这些都说,我认为可以更容易地实现目标:
re.sub(r'(?!\})\n', ' ', test);
...将替换所有不在}
前面的换行符实例。根据您尝试做的事情,这可能会更简单。
另一种选择是使用负面的后视:
re.sub(r'(?![\w-])(\n)', ' ', test);
答案 1 :(得分:1)
你犯了两个错误,你抓住了\n
并忘记了子字符串中的r
:
import re
test = '{sq-a_ foo}{sq-b_\nbar}\n{sq-c_ gluck}'
print re.sub(r'(\{*[_a-zA-Z0-9-])\n',r'\1 ',test)
此外,正如@remus所述,您可以将a-zA-Z0-9_
替换为\w
,以便简化为:
re.sub(r'(\{*[\w-])\n', r'\1 ', test)