我有某种日志文件,我想阅读和分析。不幸的是,文件被保存在一个漂亮的"丑陋的"方式(中间有很多特殊字符),所以我不能只读取每一个作为条目的行。分隔不同条目的唯一方法是使用正则表达式,因为每个条目的开头都遵循指定的模式。
我的第一种方法是识别字符向量中的模式(我使用readr-package中的read_file)并使用相应的位置将向量与strsplit分开。不幸的是,这些位置似乎并不总是匹配,因为结果并不总是与条目相对应(我猜这是特殊字符的问题)。
该文件的典型行如下所示:
16/10 / 2017,21:51 - George:这是一个典型的条目
相应的正则表达式如下所示:
([[:digit:]]{2})/([[:digit:]]{2})/([[:digit:]]{4}), ([[:digit:]]{2}):([[:digit:]]{2}) - ([[:alpha:]]+):
我想要的第一件事是data.frame,每行对应一个特定的条目(下一步我将图案分成不同的部分)。
到目前为止我尝试了以下内容:
regex.log = "([[:digit:]]{2})/([[:digit:]]{2})/([[:digit:]]{4}), ([[:digit:]]{2}):([[:digit:]]{2}) - ([[:alpha:]]+):"
log.regex = gregexpr(regex.log, file.log)[[1]]
log.splitted = substring(file.log, log.regex, log.regex[2:355]-1)
可以看出,这个日志文件有355个条目。第一个正确分开。如何使用正则表达式分离字符向量而不丢失正则表达式/模式的信息?
答案 0 :(得分:2)
使用捕获和非捕获组来识别要保留的部分,并确保使用锚点:
file.log = "16/10/2017, 21:51 - George: This is a typical entry here"
regex.log = "^((?:[[:digit:]]{2})\\/(?:[[:digit:]]{2})\\/(?:[[:digit:]]{4}), (?:[[:digit:]]{2}):(?:[[:digit:]]{2}) - (?:[[:alpha:]]+)): (.*)$"
gsub(regex.log,"\\1",file.log)
>> "16/10/2017, 21:51 - George"
gsub(regex.log,"\\2",file.log)
>> "This is a typical entry here"