简体   繁体   English

正则表达式在长文本字符串文件的特定点插入新行 \n

[英]Regex to insert new line \n at specific point in long text string file

I have text file of csv data running into 100s of thousands of what should be separate records but they forgot to put new lines into it.我有 csv 数据的文本文件运行到成千上万的应该是单独的记录,但他们忘记将新行放入其中。 There is a repeated pattern to pick out where the start of a new line should be though, before a time, a comma, and a name, eg from below "07:04:08.401,Buzzard".有一个重复的模式来选择新行的开始位置,在时间、逗号和名称之前,例如从下面“07:04:08.401,Buzzard”开始。 But because the string goes on for 1000s of lines in the file I cannot use the start ^ or end $ to anchor the string.但是因为字符串在文件中持续了 1000 行,所以我不能使用开始 ^ 或结束 $ 来锚定字符串。

My plan has been to regex from the start of each of these points backwards until the next comma so that I can then str_replace() itself back in but with "\n" on the end, thereby inserting the new lines where I want them.我的计划是从每个点的开始向后进行正则表达式,直到下一个逗号,这样我就可以将 str_replace() 本身放回原处,但以“\n”结尾,从而在我想要的地方插入新行。

I need help with both parts.我需要两个部分的帮助。

library(stringr)
library(data.table)

Data_raw <- c("07:04:08.401,Buzzard Brook,123456.78,1234567.89,196.25,-0.41,-0.60,0.07,LARS,326800.31,6749792.66,BIG Box,0.00,0.00,0.0007:04:08.401,Buzzard Brook,123456.78,1234567.89,196.25,-0.41,-0.60,0.07,LARS,123456.78,1234567.89,BIG Box,0.00,0.00,-401.3107:02:55.357,Buzzard Brook,123456.78,1234567.89,50.41,-0.42,-0.01,0.01,LARS,123456.78,1234567.89,BIG Box,Obj 2 N.A.,Obj 2 N.A.,Obj 2 N.A.07:03:10.364,Buzzard Brook,123456.78,1234567.89,50.27,-0.20,-0.03,0.00,LARS,123456.78,1234567.89,BIG Box,Obj 2 N.A.,Obj 2 N.A.,Obj 2 N.A.")

look_x <- function(rx) str_view_all(Data_raw, rx) 
look_x("[:graph:]{4}(?=\\d\\d:\\d\\d:\\d\\d.\\d\\d\\d,Buzz)")

Gets me the four preceding characters.获取前面的四个字符。 But the characters before the time back to the next comma are variable.但是时间回到下一个逗号之前的字符是可变的。 eg above they range from "0.00" to "-401.31" and "Obj 2 NA".例如上面它们的范围从“0.00”到“-401.31”和“Obj 2 NA”。 So the comma it is.所以它是逗号。 So I've been trying along the lines of:所以我一直在尝试:

look_xy("(?<=,).(?=\\d\\d:\\d\\d:\\d\\d.\\d\\d\\d,Buzz)")

..And failing to get every character preceded by "," and followed by whatever hh:mm:ss.sss,Buzz comes next. ..并且未能让每个字符都以“,”开头,然后是任何hh:mm:ss.sss,接下来是Buzz。

I also need help with the next bit would go on to do, I have tried:我还需要帮助下位将 go 上做,我试过:

Data_st_rep_all_2 <- data.frame(str_replace_all("[:graph:]{4}(?=\\d\\d:\\d\\d:\\d\\d.\\d\\d\\d,Buzz)",
                                              paste0(str_extract(Data_raw, "[:graph:]{4}(?=\\d\\d:\\d\\d:\\d\\d.\\d\\d\\d,Buzz)"),"\n"), Data_raw))

Though I am now wondering whether this will work because all the regex pieces are different.尽管我现在想知道这是否可行,因为所有正则表达式片段都不一样。

I am stuck.我卡住了。 Can anyone help?!谁能帮忙?!

There will no doubt be a very neat solution that I have totally missed!毫无疑问,我完全错过了一个非常巧妙的解决方案!

Thank you.谢谢你。

The end result should look like this:最终结果应如下所示:

Data_1 <- data.frame(Records = c("07:04:08.401,Buzzard Brook,123456.78,1234567.89,196.25,-0.41,-0.60,0.07,LARS,326800.31,6749792.66,BIG Box,0.00,0.00,0.00",
                                 "07:04:08.401,Buzzard Brook,123456.78,1234567.89,196.25,-0.41,-0.60,0.07,LARS,123456.78,1234567.89,BIG Box,0.00,0.00,-401.31",
                                 "07:02:55.357,Buzzard Brook,123456.78,1234567.89,50.41,-0.42,-0.01,0.01,LARS,123456.78,1234567.89,BIG Box,Obj 2 N.A.,Obj 2 N.A.,Obj 2 N.A.",
                                 "07:03:10.364,Buzzard Brook,123456.78,1234567.89,50.27,-0.20,-0.03,0.00,LARS,123456.78,1234567.89,BIG Box,Obj 2 N.A.,Obj 2 N.A.,Obj 2 N.A."))
mysplits <- max(lengths(strsplit(Data_1$Records, ",")))
Data_2 <- setDT(Data_1)[, paste0("column", 1:mysplits) := tstrsplit(Records, ",", fixed=T)]
Data_2[, Records := NULL]

Or rather:更确切地说:

Data_raw_2 <- c("07:04:08.401,Buzzard Brook,123456.78,1234567.89,196.25,-0.41,-0.60,0.07,LARS,326800.31,6749792.66,BIG Box,0.00,0.00,0.00\n07:04:08.401,Buzzard Brook,123456.78,1234567.89,196.25,-0.41,-0.60,0.07,LARS,123456.78,1234567.89,BIG Box,0.00,0.00,-401.31\n07:02:55.357,Buzzard Brook,123456.78,1234567.89,50.41,-0.42,-0.01,0.01,LARS,123456.78,1234567.89,BIG Box,Obj 2 N.A.,Obj 2 N.A.,Obj 2 N.A.\n07:03:10.364,Buzzard Brook,123456.78,1234567.89,50.27,-0.20,-0.03,0.00,LARS,123456.78,1234567.89,BIG Box,Obj 2 N.A.,Obj 2 N.A.,Obj 2 N.A.")
wd <- getwd()
write_lines(Data_raw_2, paste0(wd, '/', 'Data_raw_2.txt'))

Is this what you need?这是你需要的吗?

library(stringr)
str_split(Data_raw, "(?<!^)(?=\\d{2}:\\d{2}:\\d{2}\\.\\d{3},Buzzard Brook)")
[[1]]
[1] "07:04:08.401,Buzzard Brook,123456.78,1234567.89,196.25,-0.41,-0.60,0.07,LARS,326800.31,6749792.66,BIG Box,0.00,0.00,0.00"                 
[2] "07:04:08.401,Buzzard Brook,123456.78,1234567.89,196.25,-0.41,-0.60,0.07,LARS,123456.78,1234567.89,BIG Box,0.00,0.00,-401.31"              
[3] "07:02:55.357,Buzzard Brook,123456.78,1234567.89,50.41,-0.42,-0.01,0.01,LARS,123456.78,1234567.89,BIG Box,Obj 2 N.A.,Obj 2 N.A.,Obj 2 N.A."
[4] "07:03:10.364,Buzzard Brook,123456.78,1234567.89,50.27,-0.20,-0.03,0.00,LARS,123456.78,1234567.89,BIG Box,Obj 2 N.A.,Obj 2 N.A.,Obj 2 N.A."

How this works:这是如何工作的:

  • (?<!^) : negative look-behind to assert that we do not want to split at string start (?<!^) :否定后视断言我们不想在字符串开始时拆分
  • (?=\\d{2}:\\d{2}:\\d{2}\\.\\d{3},Buzzard Brook) : positive look-behind to assert that the point at which we split must be followed by a timestamp-like expression, a comma, and the string "Buzzard Brook" (?=\\d{2}:\\d{2}:\\d{2}\\.\\d{3},Buzzard Brook) :正面回顾以断言我们分裂的点必须后跟类似时间戳的表达式、逗号和字符串“Buzzard Brook”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM