【问题标题】:Replace escape sequence characters in a string in Python 3.x在 Python 3.x 中替换字符串中的转义序列字符
【发布时间】:2019-04-22 10:11:37
【问题描述】:

我已使用以下代码替换字符串中的转义字符。我首先完成了\n 和使用的re.sub() 的拆分,但我仍然不知道我错过了什么,代码没有按照预期工作。我是Python新手,所以请不要判断是否有优化问题。这是我的代码

#import sys
import re

String = "1\r\r\t\r\n2\r\r\n3\r\r\r\r\n\r\n\r4\n\r"
splitString = String.split('\n')
replacedStrings = []
i=0

for oneString in splitString:
    #oneString = oneString.replace(r'^(.?)*(\\[^n])+(.?)*$', "")
    oneString = re.sub(r'^(.?)*(\\[^n])+(.?)*$', "", oneString)
    print(oneString)
    replacedStrings.insert(i, oneString)

    i += 1

print(replacedStrings)

我的目标是:我只需要值(没有转义序列)作为拆分字符串。

我的做法是:

  1. 我已将字符串按\n 拆分,这为我提供了单独字符串的数组列表。
  2. 然后,我使用正则表达式检查了每个字符串,如果正则表达式匹配,则将匹配的子字符串替换为“”。
  3. 然后我将这些字符串推送到一个集合中,认为它将替换的字符串存储在新的数组列表中。

所以基本上,我已经完成了 1 和 2,但目前我被困在 3。以下是我的输出:

1
2
3

4

['1\r\r\t\r', '2\r\r', '3\r\r\r\r', '\r', '\r4', '\r']

【问题讨论】:

  • 虽然我不明白你的正则表达式试图实现的一切,但我看到了一个主要缺陷:你试图逐字匹配 ` while String` 不包含任何内容。 ` in String` 仅用于转义,它们不存在!
  • 哎呀。评论格式问题。 ...\` while String... The \` 在String... 也不起作用?如何在代码引用中添加反斜杠? ...反斜杠 while String...String 中的反斜杠...
  • @mkiever 不知道,我尝试了两种方法,似乎是 SO 可能想要解决的问题。

标签: python regex replace


【解决方案1】:

您可能会发现在这里使用re.findall 和简单的模式\S+ 会更容易:

input = "1\r\r\t\r\n2\r\r\n3\r\r\r\r\n\r\n\r4\n\r"
output = re.findall(r'\S+', input)
print(output)

['1', '2', '3', '4']

这种方法将隔离和匹配一个或多个非空白字符的任何孤岛。

编辑:

根据您的新输入数据,我们可以尝试匹配模式[^\r\n\t]+

input = "jkahdjkah \r\r\t\r\nA: B\r\r\nA : B\r\r\r\r\n\r\n\r4\n\r"
output = re.findall(r'[^\r\n\t]+', input)
print(output)

['jkahdjkah ', 'A: B', 'A : B', '4']

re.sub 并不是真正适合这里工作的工具。桌面上的内容是splitre.findall,因为您想重复匹配/隔离文本的某个部分。 re.sub 对于获取字符串并将其转换为其他内容很有用。它可以用于提取文本,但对于多个匹配项效果不佳。

【讨论】:

  • 此输入 "jkahdjkah \r\r\t\r\nA: B\r\r\nA : B\r\r\r\r\n\r\n\r4\n\r" 失败,输出应为我 ['jkahdjkah', 'A: B', 'A : B', 4],而输出为 ['jkahdjkah', 'A:', 'B', 'A', ':', 'B', '4']
  • @Code_Ninja 然后匹配[^\r\n\t]+, q.v.我更新的答案。
  • 这真的很酷,但我的疑问仍然存在,re.sub() 有什么问题,为什么这不起作用,您能否在答案中添加一些解释?
【解决方案2】:

你快到了,我会用string.strip() 替换字符串开头和结尾的多个\r\n

String = "1\r\r\t\r\n2\r\r\n3\r\r\r\r\n\r\n\r4\n\r"
splitString = String.split('\n')
replacedStrings = []
i=0

for oneString in splitString:
    s = oneString.strip()
    if s != '':
        print(s)
        replacedStrings.append(s)

print(replacedStrings)

输出看起来像

1
2
3
4
['1', '2', '3', '4']

对于"jkahdjkah \r\r\t\r\nA: B\r\r\nA : B\r\r\r\r\n\r\n\r4\n\r",输出将为['jkahdjkah', 'A: B', 'A : B', '4']

【讨论】:

  • 我有一个问题,你的代码运行良好,但为什么re.sub 不起作用?
  • 可能是因为替换字符串不正确!
  • IMO,更换是不必要的。 strip 可以满足您的一切需求。
  • 那么,我可以使用什么替换字符串来使该代码工作?
  • @Code_Ninja:只是为了解释为什么你的sub 没有像你预期的那样工作。您在正则表达式中使用了 start ^ 和 end $ 锚点,同时执行 sub 将匹配整个字符串,如果它完全匹配,那么整个字符串将被替换为空字符串,这不是您想要的。相反,您应该使用oneString = re.sub(r'[\r\t]+', "", oneString) 正确替换字符串中的所有\r\t,并为您提供正确的输出。
【解决方案3】:

我找到了另一种方法,这似乎工作正常,它可能不如其他答案优化,但它只是另一种方式:

import re
splitString = []
String = "jhgdf\r\r\t\r\nA  : B\r\r\nA  : B\r\r\r\r\n\r\n\rA: B\n\r"
splitString = re.compile('[\r\t\n]+').split(String)
if "" in splitString:
  splitString.remove("")
print(splitString)

我在这里添加了它,所以遇到和我一样麻烦的人可能也想忽略这种方法。

以下是我使用上述代码后得到的输出:

['jhgdf', 'A  : B', 'A  : B', 'A: B']

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-13
    • 2016-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多