Regex Отрицательный взгляд за корпусом в R - PullRequest
1 голос
/ 07 февраля 2020

Эй, я хотел бы извлечь имена из текста - моя схема идентификации заключается в том, что имена всегда начинаются с заглавной буквы, и в строке будет два или три слова с заглавной буквой. Кроме того, я объясняю тот факт, что мог существовать автор по имени «Джек младший Кости», поэтому я делаю «.» необязательный. Последним случаем может быть то, что в тексте есть учреждение со статьей, например «Театр Роберта Брауна», поэтому я хотел бы исключить все случаи, когда двум / трем словам с заглавной буквой предшествует «». Я делаю это с помощью негативного взгляда:

test <- test <- "A beautiful day for Jack Bones ended in the Robert Brown theater"
str_extract(test, "(?<!the\\s)(([A-Z][\\w]+\\s[A-Z][\\w]+[[:punct:]]?\\s[A-Z][\\w]+)|([A-Z][\\w]+\\s[A-Z][\\w]+))")
[1] "Jack Bones"

Но теперь я сталкиваюсь со следующей проблемой: если предложение начинается с «Театра Роберта Брауна», я тоже подхожу к этому шаблону. Я думал, что смогу будь умным и просто добавь "(? i) в отрицательном виде позади, но оказывается, что это не работает

test <- "The Robert Brown theater was nice, but Jack Bones did not enjoy his time there"
str_extract(test, "(?<!(?i)the\\s)(([A-Z][\\w]+\\s[A-Z][\\w]+[[:punct:]]?\\s[A-Z][\\w]+)|([A-Z][\\w]+\\s[A-Z][\\w]+))")
[1] "The Robert Brown"

Другая идея состояла в том, чтобы просто добавить условие или

str_extract(test, "(?<!(the\\s|The\\s))(([A-Z][\\w]+\\s[A-Z][\\w]+[[:punct:]]?\\s[A-Z][\\w]+)|([A-Z][\\w]+\\s[A-Z][\\w]+))")
[1] "The Robert Brown"

Тогда я попытался, сработает ли это, если использовать только «The» в отрицательном взгляде, и обнаружил, что даже это не сработает

str_extract(test, "(?<!The\\s)(([A-Z][\\w]+\\s[A-Z][\\w]+[[:punct:]]?\\s[A-Z][\\w]+)|([A-Z][\\w]+\\s[A-Z][\\w]+))")
[1] "The Robert Brown"

Теперь я немного не в курсе. Я не понимаю, почему отрицательный взгляд работает с «the», но не работает, если я использую «The». Буду признателен за любую помощь и понимание!

Ответы [ 3 ]

2 голосов
/ 08 февраля 2020

Это вариация самый большой трюк регулярного выражения :

 match_this | or_this | (but_really_keep_this)

С точки зрения R, вы можете использовать часто пропускаемое стандартное регулярное выражение функции с perl = TRUE:

test <- c("A beautiful day for Jack Bones ended in the Robert Brown theater",
          "The Robert Brown theater was nice, but Jack Bones did not enjoy his time there")

pattern <- "(?:[Tt]he\\s+(?:[A-Z][\\w.]*\\s*){2,3})(*SKIP)(*FAIL)|(?:[A-Z][\\w.]*\\s*){2,3}"

m <- gregexpr(pattern, test, perl = T)
lapply(regmatches(test, m), trimws)

, что дает

[[1]]
[1] "Jack Bones"

[[2]]
[1] "Jack Bones"


Видите ли, используемый шаблон в основном выглядит так:
The/the Word1 Word2 Word3 | (Word1 Word2 Word2)


Вы можете даже сократить свой код до очень нечитаемого однострочного (хотя это не рекомендуется):
lapply(regmatches(test, gregexpr(pattern, test, perl = T)), trimws)
1 голос
/ 08 февраля 2020

Я думаю, вам нужен негативный взгляд. Вы можете видеть это здесь

(?!(the\\s|The\\s))(([A-Z][\\w]+\\s[A-Z][\\w]+[[:punct:]]?\\s[A-Z][\\w]+)|([A-Z][\\w]+\\s[A-Z][\\w]+))

Ваш собственный regex почти сделал свое дело.

Для получения дополнительной информации об этом вы можете проверить эту ссылку

0 голосов
/ 08 февраля 2020

Наконец я также выяснил, почему мой собственный код не работает в этом примере.

Мой паттерн уже будет соответствовать "Роберту", а затем проверьте, есть ли перед или The, что, конечно, не так. Следовательно, мне нужен дополнительный взгляд в будущее на «The»:

test <- "The Robert Brown theater was nice, but Jack Bones and Hover Edgar did not enjoy his time there"
str_extract(test, "(?<![Tt]he\\s)((?!The))(([A-Z][\\w]+\\s[A-Z][\\w]+[[:punct:]]?\\s[A-Z][\\w]+)|([A-Z][\\w]+\\s[A-Z][\\w]+))")
[1] "Jack Bones"

Сокращение кода дает:

str_extract(test,"(?<![Tt]he\\s)((?!The))[A-Z][\\w]+\\s[A-Z][\\w]+([[:punct:]]\\s[A-Z][\\w]+)?")
[1] "Jack Bones"

Это решение имеет дополнительное преимущество, которое я могу оставаться в рамках str_extract и мне не нужно переходить к другой функции в R, которая допускает синтаксис Perl.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...