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



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

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

它只返回其中的第一个。

这是 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。 请注意,我们在开始时将整个文件读入单个字符串变量。 这是使用此正则表达式方法是必需的。

简单如下:

@echo off
setlocal EnableDelayedExpansion
for /F %%a in ('copy /Z "%~F0" NUL') do (set CRLF=%%a^
%Do not remove this line%
)
(for %%n in ("!CRLF!") do for /F "delims=" %%a in (input.txt) do (
set "line=%%a"
for %%d in (Z K) do set "line=!line: O%%d-=%%~nO%%d-!"
echo(!line!
)) > output.txt

如果您认为将来可能会有其他文件操作任务从通用正则表达式文本处理实用程序中受益,那么您可以考虑 JREPL.BAT。它是纯脚本(JScript/batch(,从XP开始在任何Windows机器上运行 - 不需要第三方exe文件。

jrepl "((?:[^:]*:){6}.*?) (?=O[KZ]-)" "$1rn" /xseq /f "yourFile.txt" /o -

假设O[KZ]-除了每个逻辑行的开头之外没有出现在任何其他位置,那么您应该能够摆脱这个更简单的正则表达式:

jrepl "s+(?=O[KZ]-)" "rn" /xseq /f "yourFile.txt" /o -

完整的文档内置于 JREPL 中,可通过jrepl /?jrepl /??获得分页帮助。所有选项的摘要可通过jrepl /?options获得,所有类型的帮助摘要可通过jrepl /?help获得。

最新更新