2015-05-03 2 views
3

Я хочу заменить все из списка, который НЕ соответствует данному шаблону. Я использую R версии 3.1.3 (2015-03-09) - "Smooth Sidewalk"Выделить все, кроме определенного регулярного выражения, из списка в R

Список примеров у меня есть:

y <- c("D CCNA_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_, где числа не совпадают в каждом случае, но всегда имеют 5 цифр.

Нужный выход:

"CCNA_" "CCNA_02345" "CCNA_12345" "CCNA_23468" 

до сих пор я удалил предыдущую часть на матч по:

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

, но у меня есть проблемы в признании матч с [^ матча] выражение.

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

, который производит вывод:

[1] "CCNA_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) 

reults в

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

или

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

результатов в

[1] "CCNA_0" 

Есть ли способ спецификации ify точный шаблон, который я ищу (CCNA_ [0-9] [0-9] [0-9] [0-9] [0-9])? Кроме того, существует ли возможный способ сделать это за один шаг (удалить до и после матча в одном регулярном выражении)?

Заранее благодарен!

ответ

5

Вот несколько способов:

1) strapplyc. Это использует особенно простой шаблон. Это делает использование strapplyc в пакете gsubfn:

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

Вот визуализация регулярного выражения:

CCNA_\d{5} 

Regular expression visualization

Debuggex Demo

1a) Если только вхождения CCNA_ до 5 цифр, тогда мы можем упростить предыдущий раствор иона немного как это:

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

2) суб.Картина здесь несколько сложнее, но с использованием sub мы можем сделать это без каких-либо аддонов пакетов:

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

3) strsplit Если часть хочет всегда второе «слово» (которое имеет место в вопросе), то это будет работать, и снова не требует никаких пакетов:

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

4) SUBSTR Если желаемая часть всегда символы с 3 по 12, как в вопросе, то мы могли бы использовать substr или substring, а коэффициент усиления, без каких-либо пакетов:

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

С базой R вы можете просто сделать непосредственно из исходного вектора y

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

Другой вариант заключается в использовании stringi

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

Если у вас есть более чем 1 CCNA шаблон в каждой строке использовать stri_extract_all_regex вместо этого

Если вы хотите совместить ровно 5 цифр после CCNA_ вы можете также сделать

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

И, конечно, так же с stringr

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

Вот подход с использованием пакета я поддерживать qdapRegex (я предпочитаю это или стринги/stringr) в основание для согласованности и простоты использования. Я также показываю базовый подход. В любом случае я бы рассматривал это скорее как проблему «извлечения», чем проблему «sub all but» subbing.

y <- c("D CCNA_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_" "CCNA_02345" "CCNA_12345" "CCNA_23468" 

В базовой R:

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

## [1] "CCNA_" "CCNA_02345" "CCNA_12345" "CCNA_23468" 
+0

Я думаю, вы имели в виду stringR/stringi? :) – Molx

+0

regmatches (y, regexpr ('CCNA _ \\ d {5}', y)) –

+0

@ShenglinChen есть ли что-нибудь, что вы пытаетесь сказать здесь? –

Смежные вопросы