Regex Tidyverse, как захватить выражение, если существует - PullRequest
0 голосов
/ 10 января 2019

Я использую регулярные выражения для разбора имен автомобилей.
Поскольку существует множество версий Golf, я хочу исключить все, что следует за ним, кроме Golf SportsWagen.

Моя попытка:

> some_versions <- c("Golf A5", "Golf SportsWagen", "Cross Golf", "Golf A6")
> str_replace( some_versions, "Golf( SportsWagen)?", "Golf\\1" )
[1] "Golf A5"   "Golf SportsWagen"   "Cross Golf"   "Golf A6"

Но это дает весь оригинальный вектор some_versions

Напротив, если я запускаю матчи, я получаю то, что ожидается:

> str_match(some_versions, "Golf( SportsWagen)?")
     [,1]               [,2]          
[1,] "Golf"             NA            
[2,] "Golf SportsWagen" " SportsWagen"
[3,] "Golf"             NA            
[4,] "Golf"             NA   

с NA, где нет совпадений.

Я бы хотел получить:

> str_replace(some_versions, "pattern", "Golf\\1")
> "Golf"  "Golf SportsWagen"   "Golf"   "Golf"

Кто-нибудь знает, как я могу это исправить?

Кроме того, мое следующее требование - захватить Cross Golf.

Спасибо.

1 Ответ

0 голосов
/ 10 января 2019

Я предлагаю использовать str_extract здесь вместо str_replace. str_replace заменяет соответствующий текст. str_extract извлекает подстрок, сопоставленных с более длинными строками текста.

Для решения исходной задачи вы можете использовать

str_extract(some_versions, "Golf(?: SportsWagen)?")
[1] "Golf"             "Golf SportsWagen" "Golf"             "Golf" 

Чтобы также извлечь Cross Golf, если есть Cross до Golf, используйте

str_extract(some_versions, "(?:Cross )?Golf(?: SportsWagen)?")
[1] "Golf"       "Golf"       "Cross Golf" "Golf"

Итак, (?:Cross )?Golf(?: SportsWagen)? соответствует необязательному Cross и пробелу после него, затем сопоставляется Golf, а затем сопоставляется необязательная последовательность пробелов + SportsWagen.

Замените пробелы на \\s+, чтобы они соответствовали 1 или более пробелам, и оберните слова \\b, границами слов, если вам нужно сопоставить эти строки как целые слова.

Например:

str_extract(some_versions, "\\b(?:Cross\\s+)?Golf(?:\\s+SportsWagen)?\\b")
[1] "Golf"             "Golf SportsWagen" "Cross Golf"       "Golf"  
...