这是我的第一篇文章,所以我希望它足够清楚。 我有一个关于清理我的CSV文件的问题,然后才能将它们读入R并且花了一整天的时间来寻找解决方案。
我的数据应该是两列的形式。第一列是由10位数组成的时间戳,第二列是由11或12个字母和数字组成的ID(前6个始终是数字)。
例如:
logger10 |
0821164100 | 010300033ADD
0821164523 | 010300033ADD
0821164531 | 010700EDDA0F0831102744
010700EDDA0F|
会变成:
0821164100 | 010300033ADD
0821164523 | 010300033ADD
0821164531 | 010700EDDA0F
0831102744 | 010700EDDA0F
(请原谅中间的线条,这是我试图分隔列......)。
csv文件似乎偶尔会丢失一个逗号,这意味着有时候一行最终会像这样结束:
0923120531,010300033ADD0925075301,010700EDD00A
我的硬件每次重新启动时都会添加单词logger10
(或者这个数字记录器),这会产生类似的问题,例如: logger10logger100831102744
。
我想我已经设法解决了记录器文本问题(参见代码),但我确信这可以改进。另外,我真的不想删除任何数据。 我真正的麻烦是确保在ID之后的正确位置有换行符,如果没有,我想添加一个换行符。我以为我可以使用正则表达式,但我很难理解它。
非常感谢任何帮助!
这是我的尝试:
temp <- list.files(pattern="*.CSV") #list of each csv/logger file
for(i in temp){
#clean each csv
tmp<-readLines(i) #check each line in file
tmp<-gsub("logger([0-9]{2})","",tmp) #remove logger text
pattern <- ("[0-9]{10}\\,[0-9]{6}[A-Z,0-9]{5,6}") #regex pattern ??
if (tmp!= pattern){
#I have no idea where to start here...
}
}
这里有一些原始数据: logger01 0729131218,020700EE1961 0729131226,020700EE1961 0831103159,0203000316DB 0831103207,0203000316DB0831103253,010700EDE28C 0831103301,010700EDE28C 0831103522,010300029815 0831103636,010300029815 0831103657,020300029815
答案 0 :(得分:1)
如果您想一次性完成此操作:
(?:logger\d\d )?([\dA-F]{10}),?([\dA-F]{12}) ?
可以替换为
\1\t\2\n
这样做是为了寻找任何那些流氓logger01
条目(包括它后面的空格)可选:在组之后尾随?
意味着它可以匹配0或1次:如果它 匹配,它会。如果不存在,那么比赛就会继续进行。
然后,您会查找(并捕获)10个十六进制值(数字或A-F
)。 ,?
表示如果逗号存在,它将匹配,但它也可以匹配0或1次(使其成为可选项)。
然后,查找(并捕获)正好12个十六进制值。最后,为了摆脱任何奇怪的尾随空格,?
(后跟?
的空格字符)将可选地匹配尾随空格。
您的替换将替换第一个捕获的组(10个十六进制数字),添加选项卡,替换第二个捕获的组(12个十六进制数字),然后换行。
您可以在regex101上看到此消息,以查看结果。您可以使用该页面左侧的code generator
来获取一些预先格式化的PHP / Javascript / Python,您可以将其放入脚本中。
如果您从命令行执行此操作,可以使用perl:
perl -pe 's/(?:logger\d\d )?([\dA-F]{10}),?([\dA-F]{12}) ?/\1\t\2\n/g'
如果使用其他语言,您可能需要稍微调整一下以满足您的需求。
修改强>
重新阅读OP和评论,一个稍微僵硬的正则表达式可能
(?:logger\d\d\ )?([\dA-F]{10}),?(\d{6}[\dA-F]{5,6})\ ?
我使用更改更新了regex101链接。
这仍然会查找前10个十六进制值,但现在查找正好6位数,然后是5-6个十六进制值,因此匹配的字符总数为11或12。
替换将是相同的。
答案 1 :(得分:0)
将您的正则表达式粘贴到https://regex101.com/以查看它是否捕获了所有情况。 5或6个字母或数字可能会造成问题,因为它可能会在记录器错过逗号时捕获时间戳的第一个数字。如果正则表达式捕获所有情况,则应在tmp字符串的末尾附加'\ n'。