Необязательная часть шаблона в окне поиска регулярных выражений

#r #regex #stringr

#r #регулярное выражение #stringr

Вопрос:

В приведенном ниже примере я пытаюсь извлечь текст между «Верховный суд» или «Верховный суд Соединенных Штатов» и следующей датой (включая дату). Приведенный ниже результат не соответствует моим намерениям, поскольку результат 2 включает «из Соединенных Штатов».

Я предполагаю, что ошибка связана с .*? частью, поскольку . также может совпадать с «из Соединенных Штатов». Есть идеи, как это исключить? Я думаю, в более общем плане, вопрос заключается в том, как включить необязательный «элемент» в lookbehind (что, по-видимому, невозможно, поскольку ? делает его вводом нефиксированной длины). Большое спасибо!

 library(tidyverse)
txt <- c("The US Supreme Court decided on 2 April 2020 The Supreme Court of the United States decided on 5 March 2011 also.")

str_extract_all(txt, regex("(?<=Supreme Court)(\sof the United States)?.*?\d{1,2}\s\w \s\d{2,4}"))
#> [[1]]
#> [1] " decided on 2 April 2020"                     
#> [2] " of the United States decided on 5 March 2011"
 

Создано 2021-12-09 пакетом reprex (v2.0.1)

Я также пытался

    str_extract_all(txt, regex("(?<=(Supreme Court)|(Supreme Court of the United States)).*?\d{1,2}\s\w \s\d{2,4}"))
 

однако результат тот же.

Комментарии:

1. Вы не можете решить эту проблему без дополнительных требований, потому что поиск будет совпадать с крайними левыми позициями внутри строки. Используйте групповой подход.

Ответ №1:

В этом случае я бы предпочел использовать perl движок, который реализован в Base R, а не использовать движок ICU-библиотеки, который использует stringr / stringi.

 pattern <- "Supreme Court (of the United States ?)?\K.*?\d{1,2}\s\w \s\d{2,4}"
regmatches(txt, gregexpr(pattern, txt, perl = TRUE))

[[1]]
[1] "decided on 2 April 2020" "decided on 5 March 2011"
 

Ответ №2:

Вы можете сделать это с помощью str_match_all и захвата группы:

 str_match_all(txt, regex("Supreme Court(?:\sof the United States)?(.*?\d{1,2}\s\w \s\d{2,4})")) %>% 
  .[[1]] %>% .[, 2]

[1] " decided on 2 April 2020" " decided on 5 March 2011"