【问题标题】:Python string transformationPython字符串转换
【发布时间】:2018-06-05 23:45:39
【问题描述】:

这是我通过解析文件中的数据创建的字符串:

723|NM|1|7201|QQ|1|72034|PP|1|72034N|AA|1|7203466|QW|1|72000|NM|1|7201111|NM|1

理想情况下,我想要这样的输出:

723|NM|1
7201|QQ|1
72034|PP|1
72034N|AA|1
7203466|QW|1
72000|NM|1
7201111|NM|1

由于我没有成功解析数据并动态附加它(我是 python 新手),我知道我可以通过转换此字符串获得相同的所需输出。

我进行了研究、测试并陷入困境。

基本上我需要用一个新行替换分隔符的每 3 个实例(或者,也许任何人都可以建议的更好的东西)。

非常感谢任何帮助!

谢谢

【问题讨论】:

  • 你能给我们举一个输入文件是什么样子的例子吗?
  • 当然,这是一个 xml 文件,我正在解析一个嵌套段。原生 python 不理解每个嵌套段是独立的,所以我只是将它解析为字符串,知道我可以在最后拆分每三个部分,有效地创建一个可以加载到表中的文件。

标签: python regex string


【解决方案1】:

没有正则表达式:

像这样:

s = "723|NM|1|7201|QQ|1|72034|PP|1|72034N|AA|1|7203466|QW|1|72000|NM|1|7201111|NM|1"

items = s.split("|")
print("\n".join(["|".join(items[i:i+3]) for i in range(0,len(items),3)] ))

请注意,外部join 内的[] 是故意的,以获得更好的性能(List comprehension without [ ] in Python)(即使我同意它很丑:))

结果:

723|NM|1
7201|QQ|1
72034|PP|1
72034N|AA|1
7203466|QW|1
72000|NM|1
7201111|NM|1

顺便说一句,使用正则表达式也很简单:

re.sub("(.*?\|.*?\|.*?)\|","\\1\n",s)

但如果项目的数量不能被 3 整除,则效果不佳(这可以做到,但方式更复杂)

【讨论】:

  • 是的,很好,您的打印语句中有一个额外的 [] ,但它不需要(外部连接)。你也可以这样写:print('\n'.join('|'.join(i) for i in zip(items[::3], items[1::3], items[2::3])))
  • [] 是故意的,为了更好的性能:stackoverflow.com/questions/9060653/…
  • 这工作得很好...我想我已经很接近了,现在我应该开始工作了。谢谢!
  • @AntonvBR zip(items[::3], items[1::3], items[2::3] 最好使用itertools.islice 来避免创建实际列表。如果你想按 10 个元素分组怎么办?那会很乏味:)
  • 我认为在这种特殊情况下它更具可读性。你又说对了。
【解决方案2】:

使用正则表达式解决方案:

import re

string = """723|NM|1|7201|QQ|1|72034|PP|1|72034N|AA|1|7203466|QW|1|72000|NM|1|7201111|NM|1
723|NM|1|7201|QQ|1|72034|PP|1|72034N|AA|1|7203466|QW|1|72000|NM|1|7201111|NM|1|123|NM"""

rx = re.compile(r'(?:[^|]+\|?){1,3}')

for line in string.split("\n"):
    parts = "\n".join([part.group(0).rstrip("|") for part in rx.finditer(line)])
    print(parts)

这会产生:

723|NM|1
7201|QQ|1
72034|PP|1
72034N|AA|1
7203466|QW|1
72000|NM|1
7201111|NM|1
723|NM|1
7201|QQ|1
72034|PP|1
72034N|AA|1
7203466|QW|1
72000|NM|1
7201111|NM|1
123|NM

a demo on regex101.com

【讨论】:

  • 如果元素的数量不是 3 的倍数,则删除最后一行。
  • @Jean-FrançoisFabre:更新了表达式和演示(注意第二行不能被三整除)。
  • hmmm 正在使用正则表达式,然后用大量字符串对其进行修复。这意味着您的 regex101 演示不再支持 BTW。我敢肯定它可以通过智能正则表达式完成且无需后处理,但我懒得尝试。
【解决方案3】:

你可以使用正则表达式,可以试试这个模式:

import re

pattern=r'\d+\w\|\w+\|\d'
with open('file.txt','r') as f:
    for line in f:
        match=re.findall(pattern,line)
        for i in match:
            print(i)

输出:

723|NM|1
7201|QQ|1
72034|PP|1
72034N|AA|1
7203466|QW|1
72000|NM|1
7201111|NM|1

只是为了好玩:

import re

pattern=r'\d+\w\|\w+\|\d'
for i in [re.findall(pattern,line) for line in open('file.txt','r')][0]:
    print(i)

输出:

723|NM|1
7201|QQ|1
72034|PP|1
72034N|AA|1
7203466|QW|1
72000|NM|1
7201111|NM|1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-19
    相关资源
    最近更新 更多