我有一个包含冒号分隔行的文本文件,如下所示:
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有人能建议一种使用文本编辑工具、regex或者应用程序语言(最好是批处理脚本、Java或Python )来做到这一点吗?
更新
我尝试使用python和答案中提供的regex代码:
进口csv进口re
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
它只返回其中的第一个。
发布于 2019-09-03 11:10:07
下面是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']以下是regex模式工作原理的简要总结:
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中。注意,我们在开始时将整个文件读入一个字符串变量中。这是使用正则表达式方法所必需的。
发布于 2019-09-03 13:27:51
简单到:
@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发布于 2019-09-03 14:32:02
如果您认为将来可能有更多的文件操作任务将受益于通用regex文本处理实用程序,那么您可以考虑使用JREPL.BAT。它是纯脚本(JScript/批处理)运行在任何Windows机器上从XP向前-不需要第三方执行文件。
jrepl "((?:[^:]*:){6}.*?) (?=O[KZ]-)" "$1\r\n" /xseq /f "yourFile.txt" /o -假设O[KZ]-不出现在每个逻辑行的开头以外的任何地方,那么您就可以使用这个简单的正则表达式了:
jrepl "\s+(?=O[KZ]-)" "\r\n" /xseq /f "yourFile.txt" /o -完整的文档构建在JREPL中,可通过jrepl /?或jrepl /??获得分页帮助。所有选项的摘要都可以通过jrepl /?options获得,所有类型的帮助摘要都可以通过jrepl /?help获得。
https://stackoverflow.com/questions/57770257
复制相似问题