Заменить сопоставленные шаблоны в строке на основе условия - PullRequest
1 голос
/ 02 марта 2020

У меня есть текстовая строка, содержащая цифры, буквы и пробелы. Некоторые из его подстрок являются аббревиатурами месяца. Я хочу выполнить замену шаблона на основе условий, а именно заключить аббревиатуру месяца в пробелы тогда и только тогда, когда удовлетворяет заданному условию. В качестве примера, пусть условие будет следующим: «предшествует ди git и следует буква».

Я пробовал stringr пакет, но мне не удалось объединить функции str_replace_all() и str_locate_all():

# Input:
txt = "START1SEP2 1DECX JANEND"
# Desired output:
# "START1SEP2 1 DEC X JANEND"

# (A) What I could do without checking the condition:
library(stringr)
patt_month = paste("(", paste(toupper(month.abb), collapse = "|"), ")", sep='')
str_replace_all(string = txt, pattern = patt_month, replacement = " \\1 ")
# "START1 SEP 2 1 DEC X  JAN END"

# (B) But I actually only need replacements inside the condition-based bounds:
str_locate_all(string = txt, pattern = paste("[0-9]", patt_month, "[A-Z]", sep=''))[[1]]
#      start end
# [1,]    12  16

# To combine (A) and (B), I'm currently using an ugly for() loop not shown here and want to get rid of it

Ответы [ 2 ]

4 голосов
/ 02 марта 2020

Вы ищете обходные пути:

(?<=\d)DEC(?=[A-Z])

См. демонстрацию на regex101.com .


Lookarounds обеспечивает соответствие определенной позиции без использования каких-либо символов. Они доступны перед чем-то. (называется lookbehind) или чтобы убедиться, что все, что следует, имеет определенный тип (называется lookahead). У вас есть положительные и отрицательные значения с обеих сторон, таким образом, у вас есть четыре типа (поз. / Отриц. Lookbehind / -ahead).

Краткое примечание:
  • (?=...) поз. Lookahead
  • (?!...) является нег. Lookahead
  • (?<=...) является поз. lookbehind
  • (?<!...) - это нег. взгляд назад
0 голосов
/ 02 марта 2020

Версия Base R

patt_month <- capture.output(cat(toupper(month.abb),"|"))#concatenate all month.abb with OR  
pat <- paste0("(\\s\\d)(", patt_month, ")([A-Z]\\s)")#make it a three group thing 
gsub(pattern = pat, replacement = "\\1 \\2 \\3", txt, perl =TRUE)#same result as above

Также работает для txt2 <- "START1SEP2 1JANY JANEND" из коробки.

[1] "START1SEP2 1 JAN Y JANEND"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...