File size: 7,038 Bytes
da88570
 
 
 
58c260c
da88570
 
 
 
 
 
 
 
 
 
 
 
 
 
67e898c
da88570
 
 
 
 
 
 
 
 
 
 
 
 
58c260c
 
da88570
 
58c260c
 
da88570
67e898c
58c260c
 
da88570
67e898c
58c260c
 
da88570
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3b1dbb8
da88570
 
58c260c
 
da88570
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58c260c
 
 
da88570
 
 
58c260c
 
 
 
 
 
 
 
67e898c
58c260c
 
 
 
 
 
 
 
67e898c
58c260c
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
from bs4 import BeautifulSoup, Comment
import re
from dateparser import DateDataParser


def normalize_data(input):
    def normalize_dates(input_text):
        days = r"(?:Montag|Dienstag|Mittwoch|Donnerstag|Freitag|Samstag|Sonntag|Mo|Di|Mi|Do|Fr|Sa|So)"
        months = r"(?:Januar|Februar|März|April|Mai|Juni|Juli|August|September|Oktober|November|Dezember|Jan|Feb|Mär|Apr|Mai|Jun|Jul|Aug|Sep|Okt|Nov|Dez)"

        day_month_year_pattern = r"(?:(?:\d{1,2}\.?\s*)" + months + r"\.?\s*(?:\d{2,4})?)"
        dd_mm_yyyy_pattern = r"(?:\d{1,2}[./-]\d{1,2}[./-](?:\d{4}|\d{2}))"
        iso_pattern = r"(?:\d{2,4}[./-]\d{1,2}[./-]\d{1,2})"
        german_date_pattern = day_month_year_pattern + "|" + dd_mm_yyyy_pattern + "|" + iso_pattern

        compiled_pattern = re.compile(german_date_pattern, re.VERBOSE)

        matches = compiled_pattern.findall(input_text)

        ddp = DateDataParser(languages=["de"])

        for match in matches:
            try:
                date_data = ddp.get_date_data(match)
                if date_data.date_obj.year is None:
                    normalized_date = date_data.date_obj.strftime("%d.%m")  # Ohne Jahr
                else:
                    normalized_date = date_data.date_obj.strftime("%d.%m.%Y")  # Mit Jahr
                input_text = input_text.replace(match, normalized_date)
            except Exception as e:
                print(f"Fehler bei der Verarbeitung von '{match}': {e}")

        # Ersetze alle Vorkommen von '20.03. und 21.03.2025' durch '20.03.2025 und 21.03.2025'
        german_date_pattern = r"(?<!\.)(\d{2})\.(\d{2})\.(\s*\d{2}:\d{2})?\s*(und|\+|&|bis|bis zum|-|—|–)\s*(\d{1,2})\.(\d{1,2})\.(\d{4})(\s*\d{2}:\d{2})?"
        input_text = re.sub(german_date_pattern, r" \1.\2.\7 \4 \5.\6.\7 ", input_text)

        # Ersetze alle Vorkommen von '20. und 21.03.2025' durch '20.03.2025 und 21.03.2025'
        german_date_pattern = r"(?<!\d)(\d{2})\.(\s*\d{2}:\d{2})?\s*(und|\+|&|bis|bis zum|-|—|–)\s*(\d{1,2})\.(\d{1,2})\.(\d{4})(\s*\d{2}:\d{2})?"
        input_text = re.sub(german_date_pattern, r" \1.\5.\6 \2 \3 \4.\5.\6 \7 ", input_text)

        # Ersetze alle Vorkommen von '20.03.2025 bis/bis zum 21.03.2025' durch '20.03.2025 - 21.03.2025'
        german_date_pattern = r"(\d{1,2})\.(\d{1,2})\.(\d{4})(\s*\d{2}:\d{2})?\s*(bis|bis zum|-|—|–)\s*(\d{1,2})\.(\d{1,2})\.(\d{4})(\s*\d{2}:\d{2})?"
        input_text = re.sub(german_date_pattern, r" \1.\2.\3 \4 - \6.\7.\8 \9 ", input_text)

        # Ersetze alle Vorkommen von '20.03.2025 und/& 21.03.2025' durch '20.03.2025 + 21.03.2025'
        german_date_pattern = r"(\d{1,2})\.(\d{1,2})\.(\d{4})\.?(\s*\d{2}:\d{2})?\s*(und|\+|&)\s*(\d{1,2})\.(\d{1,2})\.(\d{4})(\s*\d{2}:\d{2})?"
        input_text = re.sub(german_date_pattern, r" \1.\2.\3 \4 + \6.\7.\8 \9 ", input_text)
        return input_text

    def normalize_times(input_text):
        time_patterns = r"""
            \b
            (\d{1,2})                # Stunde (z.B. 19 oder 5)
            (?:
                [:.]                 # Trennzeichen (Doppelpunkt oder Punkt)
                (\d{2})             # Minuten (optional)
            )?
            (?:\s*(?:Uhr|h))?        # Optional "Uhr" oder "h", nur bei Minuten oder Kontext
            (?:                      # Optionaler Zeitbereich (z.B. 19-20 oder 19 bis 20)
                \s?(?:-|bis)\s?      # Trennzeichen "-" oder "bis"
                (\d{1,2})            # Endzeit-Stunde
                (?:
                    [:.]             # Trennzeichen (Doppelpunkt oder Punkt)
                    (\d{2})         # Endzeit-Minuten (optional)
                )?
                       # Optional "Uhr" oder "h" bei Endzeit
            )?
            \s*(?:Uhr|h)
            \b
        """

        def format_time(match):
            start_hour = int(match.group(1))
            start_minute = int(match.group(2) or 0)
            formatted_start = f"{start_hour:02}:{start_minute:02}"

            if match.group(3):
                end_hour = int(match.group(3))
                end_minute = int(match.group(4) or 0)
                formatted_end = f"{end_hour:02}:{end_minute:02}"
                return f"{formatted_start}-{formatted_end}"
            return formatted_start

        compiled_pattern = re.compile(time_patterns, re.VERBOSE)

        replaced_text = compiled_pattern.sub(format_time, input_text)
        return replaced_text

    def normalize_text(input_text):
        return re.sub(r"(\d)([a-zA-Z])", r"\1 \2", input_text)

    result = re.sub(r"(\d+)\\\.", r"\1.", input)
    normalized_data = normalize_times(result)
    normalized_data = normalize_dates(normalized_data)
    normalized_data = normalize_text(normalized_data)
    return normalized_data


def clean_html(html: str):
    soup = BeautifulSoup(html, "lxml")
    body_content = soup.body

    if not body_content:
        print("Kein <body>-Tag im HTML gefunden!")
        return None
    else:
        for tag in body_content.find_all(["footer", "script", "nav", "menu", "img"]):
            tag.decompose()
        header = soup.find("header")
        if header:
            header.decompose()

        for comment in body_content.find_all(string=lambda text: isinstance(text, Comment)):
            comment.extract()

        cleaned_html = body_content.prettify()
        clean_html_lines = [line for line in cleaned_html.splitlines() if line.strip()]
        cleaned_html = "\n".join(clean_html_lines)
        return cleaned_html


def strip_html_to_text(html: str):
    soup = BeautifulSoup(html, "lxml")
    return soup.get_text(separator=' ', strip=True)


# texts = [
#     "Die 18. Koblenzer Literaturtage „ganzOhr“ finden vom 22.03. bis 05.04.2025 statt. Das Programm wird im Januar 2025 veröffentlicht, der Vorverkauf startet im Februar.",
#     "15. November 2024 & 13. Dezember 2024: Kunstausstellung 'Der erweiterte Raum'",
#     "Der siebte Workshop Retrodigitalisierung findet am 20. und 21.03.2025 bei ZB MED.",
#     "2. März bis 21. März 2025 \n"
#     "**Wann?** 05.12.2024, 19:00-21:00 **Wo?** Lesesaal im Marstallgebäude, TIB",
#     "22.04.25 15 Uhr bis 23.04.25 16 Uhr."
# ]
#
# expected_texts = [
#     "Die 18. Koblenzer Literaturtage „ganzOhr“ finden vom 22.03.2025 - 05.04.2025 statt. Das Programm wird im Januar 2025 veröffentlicht, der Vorverkauf startet im Februar.",
#     "15.11.2024 + 13.12.2024: Kunstausstellung 'Der erweiterte Raum'",
#     "Der siebte Workshop Retrodigitalisierung findet am 20.03.2025 + 21.03.2025 bei ZB MED.",
#     "02.03.2025 - 21.03.2025 \n",
#     "**Wann?** 05.12.2024, 19:00-21:00 **Wo?** Lesesaal im Marstallgebäude, TIB",
#     "22.04.2025 15:00 - 23.04.2025 16:00."
#     ]
#
# for i, text in enumerate(texts):
#     normalized = normalize_data(text)
#     normalized = re.sub("\s*", " ",normalized)
#     expected = re.sub("\s*", " ",expected_texts[i])
#     if normalized == expected:
#         print("Normalization successful!")
#     else:
#         print("Normalization failed!")