簡體   English   中英

匹配正則表達式

[英]Matching regexes

我有以下代碼:

library(stringr)
library(devtools)

full_patterns <- source_gist("446417161352179ce42c")$value
literal_strings <- source_gist("21f5cf342e20c6e4a1e8")$value
literal_strings <- literal_strings[order(nchar(literal_strings), decreasing = TRUE)]

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

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, literal_strings[[i]])
}

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

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

代碼的重點是生成具有兩列的data.frame。 第一列應包含正則表達式匹配的第一部分(包含在literal_strings )。 第二列應該有正則表達式匹配的第二部分(即(?:I\\\\d-?)*I3(?:-?I\\\\d)* ,但只有當它是由相應的文本字符串開頭) 。 正則表達式的第二部分符合此處描述的規范。 簡而言之:這是一個不間斷的標記序列(即I1I2I3 ),僅包含IX標記,並且其中I3至少出現一次。 換句話說,諸如FA標記不會在此序列內出現。

為了使這項工作有效,行literal_strings <- literal_strings[order(nchar(literal_strings), decreasing = TRUE)]是至關重要的。 這對文字字符串進行排序,以便較長的字符串排在第一位。 這是因為意圖是,一旦匹配了full_patterns的一部分,就應該將其忽略。 例如,最長的literal_string是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之一,最短的是FA 但是,在這一點上(過程即將結束),我們對匹配先前的literal_string內部已經匹配的單個FA標記不感興趣。

如您所見,該代碼不起作用,因為生成的兩個列表的長度不同-它們的長度必須完全相同。 我該怎么做?

對於調試 (由於在R 3.1.2上運行此命令似乎無效):我的sessionInfo()提供:

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

看看這個:

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匹配項,從而導致差異。 我在此上花費的時間超出了合理的時間,因此,除非我缺少某些東西,否則我可能會屈服。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM