Python正则表达式替换文本中未编码的和号

5 投票
3 回答
5393 浏览
提问于 2025-04-17 09:32

我正在处理一个上游系统,这个系统有时候会发送一些文本,这些文本是要输出成HTML或XML格式的,但里面的&符号没有经过编码:

str1 = "Stay at this B&B"
str2 = "He’s going to Texas A&M"
str3 = "He’s going to a B&B and then Texas A&M"

我需要把这些没有编码的&符号替换成&,同时保留那些已经是字符引用的或者已经编码的&符号。

我不能去修复上游系统,而且因为文本有时候会部分编码,所以我也不能对整个字符串重新编码。我只是想解决这个烦人的问题,然后继续我的生活。

我用的这个正则表达式能很好地匹配到这些符号,但我在用re.sub时遇到了语法问题:

re.findall("&[^#|amp]", str3)

我不太确定怎么正确地替换文本;我觉得可能会涉及到re.group,但我在正则表达式方面的能力还不够强。

任何帮助都非常感谢。

3 个回答

0

第一个人说得差不多:

re.sub(r"&(?!#\d{4};|amp;)", "&amp", your_string)
12

如果&符号是字符实体的一部分,它可以是任何命名实体(不仅仅是&),也可以是十进制实体,或者是十六进制实体。这样应该就能涵盖所有情况:

re.sub(r'&(?![A-Za-z]+[0-9]*;|#[0-9]+;|#x[0-9a-fA-F]+;)',
       r'&', your_string)
5

我建议使用一种叫做“负向前瞻”的方法来解决这个问题。这样做的话,如果一个 & 后面跟着 #xxxx;(这里的 x 是数字)或者 amp;,那么匹配就会失败。也就是说,它只会匹配那些单独的 & 字符,并把它们替换成 &

re.sub(r"&(?!#\d{4};|amp;)", "&", your_string)

撰写回答