R中的正则表达式提取两个字符串之间的值

时间:2014-12-18 18:17:36

标签: regex r

我的行看起来像这样

 01:04:43.064 [12439] <2> xyz
 01:04:43.067 [12439] <2> a lmn
 01:04:43.068 [12439] <4> j klm
 x_times_wait to <3000>
 01:04:43.068 [12439] <4> j klm
 enter_object <5000> main k

我希望正则表达式只提取以时间戳开头的行的尖括号后面的值

这就是我所尝试的 - 假设这些行位于名为nn

的数据框中
 split<-str_split_fixed(nn[,1], ">", 2)
 split2<-data.frame(split[,2])

问题是split2给出了

   xyz
   a lmn
   j klm

   j klm
   main k

如何确保不返回空行和主k?

4 个答案:

答案 0 :(得分:3)

\d+(?::\d+){2}\.\d+\s+\[[^\]]+\]\s+<\d+>(.+)$

而不是分裂尝试匹配并抓住组1.参见演示。

https://regex101.com/r/vN3sH3/16

(?<=<\d>)拆分并获取split2

答案 1 :(得分:2)

如果时间戳被定义为1个或更多个数字后跟:,后跟1个或更多个数字,另一个:然后是1个或更多个数字,那么这个方法可能适用于你

x <- c("01:04:43.064 [12439] <2> xyz", "01:04:43.067 [12439] <2> a lmn",   
       "01:04:43.068 [12439] <4> j klm", "x_times_wait to <3000>",  
       "01:04:43.068 [12439] <4> j klm", "enter_object <5000> main k")

sub(".*> ", "", x[grepl("\\d+:\\d+:\\d+", x)])
# [1] "xyz"   "a lmn" "j klm" "j klm"

首先删除所有非时间戳元素,然后使用其余元素获取>之后的值。

答案 2 :(得分:0)

以下是基础R的方法:

正则表达式:

^(\\d{2}:){2}\\d{2}\\.\\d{3}.*>\\s*\\K.+

您可以将其与gregexpr

一起使用
unlist(regmatches(vec, gregexpr("^(\\d{2}:){2}\\d{2}\\.\\d{3}.*>\\s*\\K.+", 
                                vec, perl = TRUE)))
# [1] "xyz"   "a lmn" "j klm" "j klm"

其中vec是包含字符串的向量。

答案 3 :(得分:0)

使用rex可能会使这类任务变得更简单。

string <- "01:04:43.064 [12439] <2> xyz
01:04:43.067 [12439] <2> a lmn
01:04:43.068 [12439] <4> j klm
x_times_wait to <3000>
01:04:43.068 [12439] <4> j klm
enter_object <5000> main k"

library(rex)

timestamp <- rex(n(digit, 2), ":", n(digit, 2), ":", n(digit, 2), ".", n(digit, 3))

re <- rex(timestamp, space,
          "[", digits, "]", space,
          "<", digits, ">", space,
          capture(anything))

re_matches(string, re, global = TRUE)

#> [[1]]
#>       1
#> 1   xyz
#> 2 a lmn
#> 3 j klm
#> 4 j klm