匹配正则表达式

时间:2015-08-04 15:03:16

标签: regex r

我有这段代码:

literal_strings

代码的要点是生成一个包含两列的data.frame。第一列应包含正则表达式匹配的第一部分(包含在(?:I\\d-?)*I3(?:-?I\\d)*中)。第二列应该具有正则表达式匹配的第二部分(即I1,但 仅当 前面有相应的文字字符串时)。正则表达式的第二部分与here描述的规范相匹配。简而言之:它是一个不间断的标记序列(即I2I3IX),只包含I3个标记,至少FA发生一次。换句话说,literal_strings <- literal_strings[order(nchar(literal_strings), decreasing = TRUE)]之类的标记不会出现在此序列中。

为了完成这项工作,行full_patterns至关重要。这会对文字字符串进行排序,以便首先使用较长的字符串。这是因为一旦IFA-NR-TR-TR-FA,TR-NR-FA-NR-NR-QU-QU-NR-IFA-EX-TR-NR-FA-QU-I2-EX-II2-NR-TR-TR-I2-EX-NR-QU-EX-I2,QU-TR-NR-QU-NR-FA-TR-QU-EX-II2-I2-I2-I2-II2-FA-EX-TR-TR-QU-NR-NR-NR-TR-I2-FA-QU-ITR-EX-FA,TR-I2-NR-QU-FA-IFA-TR-EX-NR-FA-NR-FA-EX-FA-FA-QU-NR-NR-NR-INR-TR的一部分匹配,就应该忽略它。例如,最长的literal_string是FA,其中一个最短的是FA。但是,此时(在流程结束时),我们对匹配之前literal_strings内已匹配的单个sessionInfo()标记不感兴趣。

正如您所看到的,代码不起作用,因为生成的两个列表具有不同的长度 - 它们需要具有完全相同的长度。我怎么能做到这一点?

用于调试(因为在R 3.1.2上运行此功能似乎不起作用): 我的R version 3.2.0 (2015-04-16) Platform: x86_64-apple-darwin13.4.0 (64-bit) Running under: OS X 10.9.5 (Mavericks) locale: [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 attached base packages: [1] stats graphics grDevices utils datasets methods base other attached packages: [1] stringr_1.0.0 loaded via a namespace (and not attached): [1] magrittr_1.5 tools_3.2.0 stringi_0.4-1 给出了:

{{1}}

1 个答案:

答案 0 :(得分:0)

看看这个:

library(stringr)
library(devtools)
library(Hmisc)


full_patterns <- c("I2-EX-I3-EX-I2-IEX-I3-I2-EX-I2-I2-II3-I2-III2-I2-I3-INR-FA-NR-I3-INR-IEX-QU-I3-NR-FA-EX-QU-NR-I2-I2-I2-NR-TR-II2-I3-NR-IIEX")
#full_patterns <- c("I2-EX-I3-EX-I2-IEX-I3-I2-EX-I2-I2-II3-I2-III2-I2-I3-INR-FA-NR-I3-INR-IEX-QU-I3-NR-FA-EX-QU-NR-I2-I2-I2-NR-TR-II2-I3-NR-IIEX-NR-NR-INR-NR-I3-I2-NR-IQU-QU-ITR-QU-NR-NR-QU-TR-NR-ITR-IFA-II2-QU-TR-FA-EX-QU-QU-QU-NR-QU-ITR-FA-QU-FA-FA-TR-FA-QU-EX-QU-IQU-QU-FA-FA-QU-QU-FA-FA-I3-NR-FA-II2-FA-QU-FA-I2-FA-NR-INR-TR-NR-EX-NR-NR-EX-TR-I3-INR-NR-FA-ITR-EX-NR-NR-IINR-INR-EX-EX-EX-NR-NR-NR-FA-FA", "FA-I2-I2-I2-EX-I2-I3-FA-II2-TR-II2-FA-I3-IFA-FA-NR-I3-I2-TR-II2-II2-FA-I2-II3-FA-QU-II2-I2-I2-NR-I2-I2-NR-II2-INR-I3-QU-I2-I3-QU-NR-I2-INR-QU-QU-I2-IEX", "FA-FA-ITR-IIFA,TR-FA-I2-I2-FA-EX-IFA,IEX,I2-I2-INR-I2-I3-I1,TR-NR-I2-I3-EX-IQU-TR-I3-NR-EX-I3-EX,I2-EX-IIIII2-II3-I2-EX,FA-IEX-EX-TR-EX-TR-I3-INR-I2-FA-FA-TR-I2-IIIIIFA-I2-FA-TR-III3-NR-FA-III3-TR-I2-I2,I2-I2-EX,TR-TR-I2-FA-I2-I3-IIIFA-ITR-FA-IFA-INR-NR-II2-I3-I2-FA-II2-EX-FA,I3-I3-TR-I3-FA-NR-II2-II3-TR-TR-EX,I3-TR-NR-TR-QU-EX-NR-TR-I2-EX-III3-INR-INR-IFA,TR-I3-I2-I3-NR-NR-I1,IIFA-FA-IFA-FA-NR-II3-NR-I2-FA-FA-IFA-NR-FA,IFA-FA-NR-NR-I2-NR-IIIFA-EX,II2-II2-I2-QU-TR-FA-QU-I3-EX-ITR-IFA-FA-NR-INR-FA-FA-EX-II2-NR-I3,I3-FA-I2-I2-FA-I2-FA-I2,I2-INR-I2-NR-II3-TR-FA-I2-I3,I3-NR-EX-TR-IEX,II2-FA-I2-INR-I2-I3-IIEX-FA,IEX-EX-EX-EX-EX-EX-EX-TR-TR-I2-NR-NR-EX-NR-I3-FA-NR-NR-NR-EX-NR-II2-IIFA-FA-ITR-NR-I2-I3-I2-NR-FA-NR-I1")
literal_strings <- c("I2")
#literal_strings <- c("FA-QU-II2-I2-I2-NR-I2-I2-NR-II2-INR-", "QU-I2-", "QU-NR-I2-INR-QU-QU-I2-IEX-", "FA-", "QU-EX-NR-", "NR-EX-", "NR-EX-TR-", "QU-")
#full_patterns <- source_gist("446417161352179ce42c")$value
#literal_strings <- source_gist("21f5cf342e20c6e4a1e8")$value
escaped_literals <- lapply(literal_strings, escapeRegex)

regex_list <- list()
for (i in 1:length(literal_strings)){
  regex_list[i] <- paste0("(?:(?=", escapeRegex(literal_strings[i]), ")(?:I\\d-?)*I3(?:-?I\\d)*|(?=", escapeRegex(literal_strings[i]), "))")
}

IVs_identified <- list()
DVs_identified <- list()

for (i in 1:length(regex_list)){
  DVs_identified[[i]] <- lapply(full_patterns, str_extract_all, regex_list[[i]])
  IVs_identified[[i]] <- lapply(full_patterns, str_extract_all, escaped_literals[[i]])
}

unlistDVs <- unlist(DVs_identified)
unlistIVs <- unlist(IVs_identified)

for(i in 1:length(unlistDVs))
{
  print(unlistDVs[i])
  flush.console()
}

print("---------------------")

for(i in 1:length(unlistIVs))
{
  print(unlistIVs[i])
  flush.console()
}



data.frame(unlist(DVs_identified), unlist(IVs_identified))

print(length(unlist(DVs_identified)))
print(length(unlist(IVs_identified)))

我在上面的示例中删除了数据,以确定(我认为)导致差异的原因。这不起作用的原因应该是显而易见的。在我设置的小样本集中,第六个I2匹配,但由于它正确匹配正则表达式I2-I2-I3的方式,它跳过了一个literal_string匹配(有两个I2在一个合法的正则表达式匹配中)。显然,这只是一个例子,但我认为很容易看到在其他情况下发生这种情况。

我认为我构建正则表达式的方式是正确的,问题是你提供的正则表达式(?:I\\d-?)*I3(?:-?I\\d)*的可选部分有时会匹配多个literal_string匹配,这会导致出现差异。我花了更多的时间在这上面而不是可能是合理的,所以除非有一些我不知道的东西,否则我可能会退缩。