簡體   English   中英

從R中的列表中除了特定正則表達式之外的所有內容

[英]Subsititute everything except an specific regular expression from a list in R

我想替換一個與給定模式不匹配的列表中的所有內容。 我正在使用R版本3.1.3(2015-03-09) - “光滑的人行道”

我的示例列表是:

y <- c("D CCNA_01234 This is example 1 bis", "D CCNA_02345 This is example 2", "D CCNA_12345 This is example 3", "D CCNA_23468 This is example 4")

我要匹配的模式是CCNA_01234,其中數字在每種情況下都不相同,但總是5位數。

所需的輸出是:

"CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

到目前為止,我已經刪除了前一部分的比賽:

y_begin_rm <- sub("D ", "", y)

但我在識別匹配[^ match]表達式時遇到了問題。

y_CCNA_numbers <- sub("[^CCNA_[0-9][0-9][0-9][0-9][0-9]]*$", "", y_begin_rm)

產生輸出:

[1] "CCNA_01234 This is example 1 bis" "CCNA_02345 This is example 2"
[3] "CCNA_12345 This is example 3" "CCNA_23468 This is example 4"

似乎問題是匹配中指定的數字完全通過字符串查看,而不是我想要的確切組合。 因此,“這是一個例子”之后的數字正在造成很多麻煩。 當我省略數字或放置一個僅在CCNA_string之后的數字時,它可以正常工作:

y_CCNA <- sub("[^CCNA_]*$", "", y_begin_rm)

報復

[1] "CCNA_" "CCNA_" "CCNA_" "CCNA_"

要么

y_CCNA_0 <- sub("[^CCNA_0]*$", "", y_begin_rm[1])

結果是

[1] "CCNA_0"

有沒有辦法指定我正在尋找的確切模式(CCNA_ [0-9] [0-9] [0-9] [0-9] [0-9])? 此外,是否有可能在一個步驟中執行此操作(在單個正則表達式中匹配之前和之后刪除)?

提前致謝!

使用基數R,您可以直接從原始向量y

sub(".*(CCNA_\\d+).*", "\\1", y)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

另一種選擇是使用stringi

library(stringi)
stri_extract_first_regex(y, "CCNA_\\d+")
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

如果每個字符串中有多個CCNA模式,請使用stri_extract_all_regex

如果您想在CCNA_之后准確匹配5位數,您也可以這樣做

stri_extract_first_regex(y, "CCNA_\\d{5}")
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

當然與stringr類似

library(stringr)
str_extract(y, "CCNA_\\d{5}")
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

以下是幾種方法:

1)strapplyc 這使用了一種特別簡單的模式。 它在gsubfn包中使用了strapplyc

library(gsubfn)
strapplyc(y, "CCNA_\\d{5}", simplify = TRUE)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

這是正則表達式的可視化:

CCNA_\d{5}

正則表達式可視化

Debuggex演示

1a)如果CCNA_的唯一出現在5位之前,那么我們可以稍微簡化以前的解決方案:

strapplyc(y, "CCNA_.{5}", simplify = TRUE)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

2)分 這里的模式稍微復雜一些,但使用sub我們可以在沒有任何插件包的情況下完成:

sub(".*(CCNA_\\d{5}).*", "\\1", y)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

3)strsplit如果所需的部分總是第二個“單詞”(在問題中是這種情況)那么這將起作用並且再次不需要包:

sapply(strsplit(y, " "), "[", 2)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

4)substr如果所需部分始終是問題中的字符3到12,那么我們可以再次使用substrsubstring ,而不使用任何包:

substr(y, 3, 12)
## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

這是一種使用包維護qdapRegex (我更喜歡這個或stringi / stringr)的方法,以確保一致性和易用性。 我還展示了一種基本方法。 在任何情況下,我都將此視為一個“提取”問題,而不是“除了一切”之外的問題。

y <- c("D CCNA_01234 This is example 1 bis", "D CCNA_02345 This is example 2", 
    "D CCNA_12345 This is example 3", "D CCNA_23468 This is example 4")

library(qdapRegex)
unlist(rm_default(y, pattern = "CCNA_\\d{5}", extract = TRUE))

## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

在基地R:

unlist(regmatches(y, gregexpr("CCNA_\\d{5}", y)))

## [1] "CCNA_01234" "CCNA_02345" "CCNA_12345" "CCNA_23468"

暫無
暫無

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

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