Extract date from string in date format, add n number of days. to then replace with that modified data another substring within the original string

Question:

import re, datetime, time

input_text = "tras la aparicion del objeto misterioso el 2022-12-30 visitamos ese sitio nuevamente revisando detras de los arboles pero recien tras 3 dias ese objeto aparecio de nuevo tras 2 arboles" #example 1
input_text = "luego el 2022-11-15 fuimos nuevamente a dicho lugar pero nada ocurrio y 3 dias despues ese objeto aparecio en el cielo durante el atardecer de aquel dia de verano" #example 2
input_text = "Me entere del misterioso suceso ese 2022-11-01 y el 2022-11-15 fuimos al monte pero nada ocurrio, pero luego de 13 dias ese objeto aparecio en el cielo" #example 3


identified_referencial_date = r"(?P<year>d*)-(?P<month>d{2})-(?P<startDay>d{2})" #obtained with regex capture groups

# r"(?:luego[s|]*de[s|]*unos|luego[s|]*de|pasados[s|]*ya[s|]*unos|pasados[s|]*unos|pasados[s|]*ya|pasados|tras[s|]*ya|tras)[s|]*d*[s|]*(?:días|dias|día|dia)"
# r"d*[s|]*(?:días|dias|día|dia)[s|]*(?:despues|luego)"
n =       #the number of days that in this case should increase

indicated_date_relative_to_another = str(identified_date_in_date_format - datetime.timedelta(days = int(n) ))

input_text = re.sub(identified_referencial_date, indicated_date_relative_to_another, input_text)

print(repr(input_text)) # --> output

The objective is that if a day is indicated first in the format year-month-day (are integers separated by hyphens in that order) d*-d{2}-d{2} and then it says that n amount of days have passed, so you would have to replace that sentence with year-month-day+n

luego de unos 3 dias —> add 3 days to a previous date

luego de 6 dias —> add 6 days to a previous date

pasados ya 13 dias —> add 13 days to a previous date

pasados ya unos 48 dias —> add 48 days to a previous date

pasados unos 36 dias —> add 36 days to a previous date

pasados 9 dias —> add 9 days to a previous date

tras ya 2 dias —> add 2 days to a previous date

tras 32 dias —> add 32 days to a previous date

3 dias despues —> add 3 days to a previous date

3 dias luego —> add 3 days to a previous date

Keep in mind that in certain cases, increasing the number of days could also change the number of the month or even the year, as in example 1.

Outputs that I need obtain in each case:

"tras la aparicion del objeto misterioso el 2022-12-30 visitamos ese sitio nuevamente revisando detras de los arboles pero recien 2023-01-02 ese objeto aparecio de nuevo tras 2 arboles" #for the example 1

"luego el 2022-11-15 fuimos nuevamente a dicho lugar pero nada ocurrio y 2022-11-18 ese objeto aparecio en el cielo durante el atardecer de aquel dia de verano" #for the example 2

"Me entere del misterioso suceso ese 2022-11-01 y el 2022-11-15 fuimos al monte pero nada ocurrio, pero 2022-11-28 ese objeto aparecio en el cielo" #for the example 3

Answers:

Here is a regex solution you could use:

([12]d{3}-[01]d-[0-3]d)(D*?)(?:(?:luego de|pasados|tras)(?: ya)?(?: unos)? (d+) dias|(d+) dias (?:despues|luego))

This regex requires that there are no other digits between the date and the days. It also is a bit loose on grammar. It would also match "luego de ya 3 dias". You can of course make it more precise with a longer regex, but you get the picture.

In a program:

from datetime import datetime, timedelta
import re

def add(datestr, days):
    return (datetime.strptime(datestr, "%Y-%m-%d") 
            + timedelta(days=int(days))).strftime('%Y-%m-%d')

input_texts = [
    "tras la aparicion del objeto misterioso el 2022-12-30 visitamos ese sitio nuevamente revisando detras de los arboles pero recien tras 3 dias ese objeto aparecio de nuevo tras 2 arboles",
    "luego el 2022-11-15 fuimos nuevamente a dicho lugar pero nada ocurrio y 3 dias despues ese objeto aparecio en el cielo durante el atardecer de aquel dia de verano",
    "Me entere del misterioso suceso ese 2022-11-01 y el 2022-11-15 fuimos al monte pero nada ocurrio, pero luego de 13 dias ese objeto aparecio en el cielo"
]

for input_text in input_texts:
    result = re.sub(r"([12]d{3}-[01]d-[0-3]d)(D*?)(?:(?:luego de|pasados|tras)(?: ya)?(?: unos)? (d+) dias|(d+) dias (?:despues|luego))",
                    lambda m: m[1] + m[2] + add(m[1], m[3] or m[4]), 
                    input_text)
    print(result)
Answered By: trincot