2016-11-10 3 views
1

Предположим, у меня есть следующие строки (имя файла):Извлечение 2 части строки

a <- "X/ZHEB100/TKN_VAR29380_timely_p1.txt" 

, который состоит из нескольких частей (здесь дается p1)

или еще один

b <- "X/ZHEB100/ZHN_VAR29380_timely.txt" 

, который состоит только из одной части (поэтому нет необходимости наклеивать какие-либо р)

Как извлечь идентификатор r, который является тремя буквами до VARXXXXX (так в случае, если один из них будет TKN, а в случае два - ZHN). PLUS идентификатор части, если таковой имеется?

Так что результат должен быть:

case1 : TKN_p1 
case2 : ZHN 

Я знаю, как извлечь первый идентификатор, но я не могу справиться с второй в то же время.

Мой подход до сих пор:

sub(".*(.{3})_VAR29380_timely(.{3}).*","\\1\\2", a) 
sub(".*(.{3})_VAR29380_timely(.{3}).*","\\1\\2", b) 

, но это добавляет .tx неправильно во втором случае.

+0

Попробуйте 'югу ("^*/([AZ] {3}) _ [^/_] + _ [^/_] + (_ [^ _. /] +)? \\. [^.] * $ "," \\ 1 \\ 2 ", a)' –

+0

Возможно, сначала проверите идентификатор, например 'stringr :: str_match (строка, '_p. \\. txt')', а затем использовать два гораздо простых регулярных выражения? –

+0

@ WiktorStribiżew, который не работает во втором случае. – user3032689

ответ

2

Вы не используете анкеры и сопоставляете последние 3 символа сразу после timely, не проверяя, что представляют собой эти символы (. соответствует любому персонажу).

Я предлагаю

sub("^.*/([A-Z]{3})_VAR\\d+_timely(_[^_.]+)?\\.[^.]*$", "\\1\\2", a) 

Детали:

  • ^ - начало строки
  • .*/ - часть строки, вплоть до последнего /
  • ([A-Z]{3}) - 3 ASCII прописные буквы комплекс- ного в 1-й группе
  • _VAR\\d+_timely - _VAR + 1 или более цифр + _timely
  • (_[^_.]+)? - дополнительная группа 2 захвата других _ + 1 или больше символов, чем _ и .
  • \\. - точка
  • [^.]* - ноль или более символов, кроме .
  • $ - конец строки.

Образец замены содержит 2 обратных ссылки обеим группам захвата для вставки их содержимого в замененную строку.

R demo:

a <- "X/ZHEB100/TKN_VAR29380_timely_p1.txt" 
a2 <- sub("^.*/([A-Z]{3})_VAR\\d+_timely(_[^_.]+)?\\.[^.]*$", "\\1\\2", a) 
a2 
[1] "TKN_p1" 
b <- "X/ZHEB100/ZHN_VAR29380_timely.txt" 
b2 <- sub("^.*/([A-Z]{3})_VAR\\d+_timely(_[^_.]+)?\\.[^.]*$", "\\1\\2", b) 
b2 
[1] "ZHN" 
+0

Кроме того, здесь [regex demo] (https://regex101.com/r/HjM4dl/1). –

1

Просто еще одно решение, что-то отличное от уже работающего решения Wiktor в:

library(magrittr) 
data <- c(a, b) 

сначала получить значение "ID" расщепление на "/", принимая последний и первые три символа которого:

ID <- strsplit(data, "/") %>% 
    sapply(tail, n = 1) %>% 
    substr(1, 3) 

Затем получить «часть» значения, разделив из обоих «своевременной» и «.txt», и взяв последний элемент (который может быть пустой строкой):

part <- strsplit(data, "timely|.txt") %>% 
    sapply(tail, n = 1) 

Теперь просто вставьте их вместе в результате :

output <- paste0(ID, part) 
output 
[1] "TKN_p1" "ZHN" 

Или, если вы не хотите создавать промежуточные объекты:.

output <- strsplit(data, "/") %>% 
    sapply(tail, n = 1) %>% 
    substr(1, 3) %>% 
    paste0(strsplit(data, "timely|.txt") %>% 
         sapply(tail, n = 1)) 
Смежные вопросы