首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用应用程序语言(最好是批处理脚本)拆分具有可变发生次数的字符串。

使用应用程序语言(最好是批处理脚本)拆分具有可变发生次数的字符串。
EN

Stack Overflow用户
提问于 2019-09-03 10:55:33
回答 3查看 106关注 0票数 2

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

代码语言:javascript
复制
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&-,其中&只能是ZK。因此,上述预期产出如下:

代码语言:javascript
复制
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

代码语言:javascript
复制
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

它只返回其中的第一个。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-09-03 11:10:07

下面是Python中基于正则表达式的解决方案,它似乎运行得很好:

代码语言:javascript
复制
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)

这些指纹:

代码语言:javascript
复制
['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模式工作原理的简要总结:

代码语言:javascript
复制
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中。注意,我们在开始时将整个文件读入一个字符串变量中。这是使用正则表达式方法所必需的。

票数 1
EN

Stack Overflow用户

发布于 2019-09-03 13:27:51

简单到:

代码语言:javascript
复制
@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
票数 0
EN

Stack Overflow用户

发布于 2019-09-03 14:32:02

如果您认为将来可能有更多的文件操作任务将受益于通用regex文本处理实用程序,那么您可以考虑使用JREPL.BAT。它是纯脚本(JScript/批处理)运行在任何Windows机器上从XP向前-不需要第三方执行文件。

代码语言:javascript
复制
jrepl "((?:[^:]*:){6}.*?) (?=O[KZ]-)" "$1\r\n" /xseq /f "yourFile.txt" /o -

假设O[KZ]-不出现在每个逻辑行的开头以外的任何地方,那么您就可以使用这个简单的正则表达式了:

代码语言:javascript
复制
jrepl "\s+(?=O[KZ]-)" "\r\n" /xseq /f "yourFile.txt" /o -

完整的文档构建在JREPL中,可通过jrepl /?jrepl /??获得分页帮助。所有选项的摘要都可以通过jrepl /?options获得,所有类型的帮助摘要都可以通过jrepl /?help获得。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57770257

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档