首页 > 解决方案 > 使用应用程序语言(最好是批处理脚本)拆分出现次数可变的字符串

问题描述

我有一个包含冒号分隔行的文本文件,如下所示:

OK-10:Jason:Jones:ID No:00000000:male:my notes                                                                                                                                                       
OK-10:Mike:James:ID No:00000001:male:my notes OZ-09:John:Rick:ID No:00000002:male:my notes
OK-08:Michael:Knight:ID No:00000004:male:my notes2 OK-09:Helen:Rick:ID No:00000005:female:my notes3 OZ-10:Jane:James:ID No:00000034:female:my notes23 OK-09:Mary:Jane:ID No:00000023:female:my notes46

请注意,并非所有行都具有相同数量的术语。我希望每一行都像第一行一样,即只有七个词。对于超出的线路,应形成一条新线路。新行分隔符是O&-可以&Z唯一K的地方。所以上面的预期输出是:

OK-10:Jason:Jones:ID No:00000000:male:my notes                                                                                                                                                       
OK-10:Mike:James:ID No:00000001:male:my notes
OZ-09:John:Rick:ID No:00000002:male:my notes
OK-08:Michael:Knight:ID No:00000004:male:my notes2
OK-09:Helen:Rick:ID No:00000005:female:my notes3
OZ-10:Jane:James:ID No:00000034:female:my notes23
OK-09:Mary:Jane:ID No:00000023:female:my notes46

有人可以建议一种使用文本编辑工具、正则表达式或应用程序语言(例如(最好)批处理脚本、Java 或 Python)的方法吗?

更新

我尝试使用 python 和答案中提供的正则表达式代码:

导入 csv 导入重新

with open('form.csv') as csv_file:
    csv_reader = csv.reader(csv_file, delimiter=',')
    for row in csv_reader:
        matches = re.findall(r'O[KZ]-\d+:(?:[^:]+:){5}.*?(?= O[KZ]|$)', row[29])
        print(matches)

但是,如果一个单元格包含多个条目,例如:

OK-10:Mike:James:ID No:00000001:male:my notes OZ-09:John:Rick:ID No:00000002:male:my notes

它只返回其中的第一个。

标签: stringbatch-filesplit

解决方案


这是 Python 中基于正则表达式的解决方案,它似乎运行良好:

with open('form.csv', 'r') as file:
    inp = file.read().replace('\n', '')

matches = re.findall(r'O[KZ]-\d+:(?:[^:]+:){5}.*?(?= O[KZ]|$)', inp)
print(matches)

这打印:

['OK-10:Mike:James:ID No:00000001:male:my notes',
 'OK-08:Michael:Knight:ID No:00000004:male:my notes2',
 'OK-09:Helen:Rick:ID No:00000005:female:my notes3',
 'OZ-10:Jane:James:ID No:00000034:female:my notes23',
 'OK-09:Mary:Jane:ID No:00000023:female:my notes46']

以下是正则表达式模式如何工作的简要总结:

O[KZ]-\d+:      match the first OK/OZ-number term
(?:[^:]+:){5}   then match the next five : terms
.*?(?= O[KZ]|$) finally match the remaining sixth term
                until seeing either OK/OZ or the end of the input

我的脚本生成的输出是一个列表,然后您可以将其写回文本文件,以便稍后导入 MySQL。请注意,我们在开始时将整个文件读入单个字符串变量。这是使用这种正则表达式方法所必需的。


推荐阅读