#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"