Вычитание дней из даты в текстовом поле

У меня есть текст, который выглядит так:

"Word1 word2 word3 word4 12/31/1980 word word words"  
"Word1 word2 word3 11/2/90 word word words 10/2/1991."   
"Word1 8/1/2003 word2 word3 word4 11/8/1990 word word words October 4, 1997 words." 

Я хочу заменить текущие даты днями между датами в тексте и другой датой.

Так, например, в этом случае:

"Word1 word2 word3 word4 1000 word word words"  
"Word1 word2 word3 2000 word word words 2365."  
"Word1 4000 word2 word3 word4 4005 word word words 5000 words." 

(Кстати, я придумал номера замены.)

У меня были некоторые проблемы с mdy(), правильно определяющим год. До сих пор мое решение представляло собой двухэтапный процесс извлечения и форматирования даты, а затем ее прохождение и замену в текстовом поле.

# extract and format 2 digit year dates

    re <- ".*\\s+(\\d{1,2}/\\d{1,2}/\\d{2})\\D.*" 
    path$path_date_magic_2year <- mdy(with(path, ifelse(grepl(re,   path_notes),sub(re,'\\1',path_notes),'')))

# replace the date in the text with the extracted and formatted date 
    for (i in 1:length(path$path_date_magic_2year)){
      if (!is.na(path$path_date_magic_2year[i])) {
        path$path_date_magic_2year_test[i] <- sub('\\d{1,2}/\\d{1,2}/\\d{2}',              path$path_date_magic_2year[i] , path$path_notes[i])
  }
}

(После того, как я укажу даты года из 2 цифр, затем я сделаю даты года из 4 цифр, а затем выпишу даты месяца. Теоретически mdy() обрабатывает все это, но не все из них были правильными, когда я сделал это изначально, будучи почти идеально в разлуке)

Так вот что.

Когда в текстовом поле указана только одна дата, работает текущий метод.

Итак, моя оставшаяся проблема заключается в том, как обрабатывать случай, когда в тексте более одной даты. У меня есть от 1 до 6 дат в свободном текстовом поле.

Что я хотел бы сделать, так это исправить все это за один шаг, независимо от количества дат в текстовом поле, используя gsub для жадной замены. Однако я еще не нашел способа заставить это работать.

Любые идеи, как я могу заставить это работать?


person soporific    schedule 10.04.2015    source источник


Ответы (1)


Предполагая, что вектор txt содержит ваш текст, а myDate является уменьшаемым:

myDate <- Sys.Date() # for example
Sys.setlocale("LC_TIME", "english") # if needed
regex <- paste0("\\d{1,2}/\\d{1,2}/\\d{2,4}", "|((", paste(month.name, collapse = "|"), ") \\d{1,2}, \\d{2,4})")
days <- sapply(lapply(matches <- regmatches(txt, gregexpr(regex, txt)), function(x) if (length(x)) as.Date(x, lubridate::guess_formats(x, "mdy"))) , function(date) as.numeric(myDate - date))
for (x in seq_along(txt)) 
  for (y in seq_along(days[[x]])) 
    txt[x] <- sub(matches[[x]][y], days[[x]][y], txt[x], fixed = TRUE)
# [1] "Word1 word2 word3 word4 12518 word word words"                
# [2] "Word1 word2 word3 8925 word word words 8591."                 
# [3] "Word1 4270 word2 word3 word4 8919 word word words 6397 words."
person lukeA    schedule 10.04.2015
comment
Спасибо!! Это полностью сработало, как только я отследил одно поле с трехзначным годом :) - person soporific; 11.04.2015