File size: 32,577 Bytes
9b0e5e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83f1514
 
 
9b0e5e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
import spacy
from spacy import displacy
from spacy.util import compile_prefix_regex, compile_suffix_regex, compile_infix_regex
from spacy.tokenizer import Tokenizer
from spacy.language import Language

from src.nlp.data.test_texts import TEXTS
from src.utils.helpers import normalize_data
from src.utils.markdown_processing.CustomMarkdownAnalyzer.MarkdownAnalyzer import MarkdownAnalyzer
from spacy.tokens import Span


class Token:
    def __init__(self, text):
        self.text = text


    def __repr__(self):  # Automatische Ausgabe in print() oder Listen
        return self.text


stop_words = ["*","a","aber","ach","acht","achte","achten","achter","achtes","ag","alle","allein","allem","allen","aller","allerdings","alles","allgemeinen","als","also","ander","andere","anderem","anderen","anderer","anderes","anderm","andern","anderer","anders","au","auch","auf","aus","ausser","ausserdem","außer","außerdem","b","bald","bei","beide","beiden","beim","beispiel","bekannt","bereits","besonders","besser","besten","bin","bisher","bist","c","d","d.h","da","dabei","dadurch","dafür","dagegen","daher","dahin","dahinter","damals","damit","daneben","dank","dann","daran","darauf","daraus","darf","darfst","darin","darum","darunter","darüber","das","dasein","daselbst","dass","dasselbe","davon","dazu","dazwischen","daß","dein","deine","deinem","deinen","deiner","deines","dem","dementsprechend","demgegenüber","demgemäss","demgemäß","demselben","demzufolge","den","denen","denn","denselben","der","deren","derer","derjenige","derjenigen","dermassen","dermaßen","derselbe","derselben","des","deshalb","desselben","dessen","deswegen","dich","die","diejenige","diejenigen","dies","diese","dieselbe","dieselben","diesem","diesen","dieser","dieses","dir","doch","dort","drei","drin","dritte","dritten","dritter","drittes","du","durch","durchaus","durfte","durften","dürfen","dürft","e","eben","ebenso","ehrlich","ei","ei,","eigen","eigene","eigenen","eigener","eigenes","ein","einander","eine","einem","einen","einer","eines","einig","einige","einigem","einigen","einiger","einiges","einmal","eins","elf","en","ende","endlich","entweder","er","ernst","erst","erste","ersten","erster","erstes","es","etwa","etwas","euch","euer","eure","eurem","euren","eurer","eures","f","folgende","früher","fünf","fünfte","fünften","fünfter","fünftes","für","g","gab","ganz","ganze","ganzen","ganzer","ganzes","gar","gedurft","gegen","gegenüber","gehabt","gehen","geht","gekannt","gekonnt","gemacht","gemocht","gemusst","genug","gerade","gern","gesagt","geschweige","gewesen","gewollt","geworden","gibt","ging","gleich","gott","gross","grosse","grossen","grosser","grosses","groß","große","großen","großer","großes","gut","gute","guter","gutes","h","hab","habe","haben","habt","hast","hat","hatte","hatten","hattest","hattet","heisst","her","heute","hier","hin","hinter","hoch","hätte","hätten","i","ich","ihm","ihn","ihnen","ihr","ihre","ihrem","ihren","ihrer","ihres","im","immer","in","indem","infolgedessen","ins","irgend","ist","j","ja","jahr","jahre","jahren","je","jede","jedem","jeden","jeder","jedermann","jedermanns","jedes","jedoch","jemand","jemandem","jemanden","jene","jenem","jenen","jener","jenes","jetzt","k","kam","kann","kannst","kaum","kein","keine","keinem","keinen","keiner","keines","kleine","kleinen","kleiner","kleines","kommen","kommt","konnte","konnten","kurz","können","könnt","könnte","l","lang","lange","leicht","leide","lieber","los","m","machen","macht","machte","mag","magst","mahn","mal","man","manche","manchem","manchen","mancher","manches","mann","mehr","mein","meine","meinem","meinen","meiner","meines","mensch","menschen","mich","mir","mit","mittel","mochte","mochten","morgen","muss","musst","musste","mussten","muß","mußt","möchte","mögen","möglich","mögt","müssen","müsst","müßt","n","na","nach","nachdem","nahm","natürlich","neben","nein","neue","neuen","neun","neunte","neunten","neunter","neuntes","nicht","nichts","nie","niemand","niemandem","niemanden","noch","nun","nur","o","ob","oben","oder","offen","oft","ohne","ordnung","p","q","r","recht","rechte","rechten","rechter","rechtes","richtig","rund","s","sa","sache","sagt","sagte","sah","satt","schlecht","schluss","schon","sechs","sechste","sechsten","sechster","sechstes","sehr","sei","seid","seien","sein","seine","seinem","seinen","seiner","seines","seit","seitdem","selbst","sich","sie","sieben","siebente","siebenten","siebenter","siebentes","sind","so","solang","solche","solchem","solchen","solcher","solches","soll","sollen","sollst","sollt","sollte","sollten","sondern","sonst","soweit","sowie","später","startseite","statt","steht","suche","t","tag","tage","tagen","tat","teil","tel","tritt","trotzdem","tun","u","uhr","und","uns","unse","unsem","unsen","unser","unsere","unserer","unses","unter","v","vergangenen","viel","viele","vielem","vielen","vielleicht","vier","vierte","vierten","vierter","viertes","vom","von","vor","w","wahr","wann","war","waren","warst","wart","warum","was","weg","wegen","weil","weit","weiter","weitere","weiteren","weiteres","welche","welchem","welchen","welcher","welches","wem","wen","wenig","wenige","weniger","weniges","wenigstens","wenn","wer","werde","werden","werdet","weshalb","wessen","wie","wieder","wieso","will","willst","wir","wird","wirklich","wirst","wissen","wo","woher","wohin","wohl","wollen","wollt","wollte","wollten","worden","wurde","wurden","während","währenddem","währenddessen","wäre","würde","würden","x","y","z","z.b","zehn","zehnte","zehnten","zehnter","zehntes","zeit","zu","zuerst","zugleich","zum","zunächst","zur","zurück","zusammen","zwanzig","zwar","zwei","zweite","zweiten","zweiter","zweites","zwischen","zwölf","über","überhaupt","übrigens"]


nlp = spacy.blank("de")

config = {"punct_chars": [".", "!", "?"]}

nlp.add_pipe('sentencizer', config=config)



@Language.component("custom_sentence_boundary")
def custom_sentence_boundary(doc):
    for token in doc[:-1]:
        if token.text.endswith(".") and token.nbor(1).is_digit:
            doc[token.i + 1].is_sent_start = False
    return doc

def remove_stopwords(text):
    doc = nlp(text)  # Tokenisiere den Text
    filtered_tokens = [token.text for token in doc if token.text.lower() not in stop_words]
    return " ".join(filtered_tokens)  # Rekonstruiere den Text ohne Stopwords

def extract_entity_context(doc, entity_label="DATE", window_size=2):
    contexts = []
    for ent in doc.ents:
        print(ent.text, ": ", ent.label_)
        # if ent.label_ == entity_label:

        # Hole das direkte Umfeld (window_size Tokens davor und danach)
        start = max(0, ent.start - window_size)  # Anfang der Umgebung

        end = min(len(doc), ent.end + window_size)  # Ende der Umgebung

        for other_ent in doc.ents:
            if other_ent.start <= start < other_ent.end:  # Start in einer Entität?
                start = other_ent.start
            if other_ent.start < end <= other_ent.end:  # End in einer Entität?
                end = other_ent.end

        context = doc[start:end].text
        contexts.append((ent.text, context))

    return contexts

def extract_tokens_between_entities(doc):
    entities = list(doc.ents)  # Alle Entitäten im Text
    tokens_between = []

    if len(entities) < 2:
        return tokens_between  # Wenn es weniger als 2 Entitäten gibt, gibt es kein "Dazwischen"

    for i in range(len(entities) - 1):
        ent1 = entities[i]
        ent2 = entities[i + 1]

        # Speichere nur Tokens zwischen ent1 und ent2
        tokens_between.append(doc[ent1.end:ent2.start])

    return tokens_between

def find_strong_relations(sequence):

    sequence = [s for s in sequence if len(s.text)>1]
    strong_relations = []
    curr_relation = [sequence[0]]
    sequence.pop(0)
    for i,token in enumerate(sequence):
        if isinstance(token, Span):
            label = token.label_
            curr_relation.append(token)
        elif i+1 < len(sequence):
            if isinstance(sequence[i+1], Span):
                strong_relations.append(curr_relation)
                curr_relation=[token]
            else:
                curr_relation.append(token)
    strong_relations.append(curr_relation)

    return strong_relations

nlp.add_pipe("custom_sentence_boundary", after="sentencizer")

texts = [
    "Am 01.01.2020 findet die Veranstaltung statt, Einlass ist um 15:00",
    "** Die Veranstaltung beginnt am 24.12.2025 um 16:00, Einlass ist ab 15:30. **",
    "Wann: 03.03.2020 16:00, Einlass: 15:00",
    "Wann? 25.04.2025 - 23.05.2020, 15:00 bis 16:00. Abendkasse ab 14:30",
    """
    Termine: \n
    23.05.2024 19:00 \n
    22.06.2022 18:00 \n
    23.12.2030 17:00-18:00
    """,
    "#  Technik-Salon an der TIB: „FLY ROCKET FLY“\n\nÜber den Aufstieg und Fall des Raketenpioniers Lutz Kayser – ein Film- und\nGesprächsabend mit dem Dokumentarfilmer Oliver Schwehm\n\nEin Start-Up aus dem Schwäbischen, 170 Millionen D-Mark Wagniskapital, ein\nprivates Testgelände im afrikanischen Dschungel – so trat Lutz Kayser in den\n1970 er-Jahren an, die Raumfahrt zu revolutionieren.\n\nWarum das gut hätten klappen können und schließlich doch scheiterte, schildert\nOliver Schwehm in seiner bildreichen Dokumentation. Im Rahmen der\nJubiläumstour zu Ehren von Lutz Kayser („50 Jahre OTRAG – Oribital Transport\nund Raketen AG“) machen Film und Regisseur am 05.12.2024 im Technik-\nSalon Station in der TIB in Hannover. Der Eintritt für die Veranstaltung „FLY\nROCKET FLY“ ist frei (Spendenbox).\n\n**Wann?** 05.12.2024, 19:00-21:00  \n**Wo?** Lesesaal im Marstallgebäude, TIB\n\n",
    "#  7. Workshop Retrodigitalisierung\n\nThema: Digitalisierte Sammlungen präsentieren – Konzeptionierung, Darstellung\nund Vermittlung\n\nDer siebte Workshop Retrodigitalisierung findet am 20.03.2025 und 21.03.2025 bei\nZB MED – Informationszentrum Lebenswissenschaften in Köln statt. Er richtet\nsich an Praktiker:innen, die sich in Bibliotheken mit der Retrodigitalisierung\nbefassen. Wie in den Vorjahren bietet der Workshop ein breites Spektrum an\ninteressanten Vorträgen zur Praxis der Retrodigitalisierung. Dafür brauchen\nwir Sie und Ihre Einreichungen!\n\nIm Fokus des nächsten Workshops steht die zeitgemäße Präsentation\ndigitalisierter Sammlungen. Das Programm widmet sich insbesondere den Themen\nKonzeptionierung, Darstellung und Vermittlung von digitalisierten Sammlungen\nund Beständen über die Präsentationsplattformen der Einrichtungen rund um die\nNutzung von Digitalisaten.\n\nDer Call for Presentations läuft noch bis zum 18.10.2024. Wir freuen uns\nauf Ihren Beitrag!\n\nDer Workshop Retrodigitalisierung wird gemeinsam von den drei deutschen\nZentralen Fachbibliotheken TIB – Leibniz-Informationszentrum Technik und\nNaturwissenschaften, ZB MED – Informationszentrum Lebenswissenschaften und ZBW\n– Leibniz-Informationszentrum Wirtschaft sowie der Staatsbibliothek zu Berlin\n– Preußischer Kulturbesitz durchgeführt.\n\n**Wann?** 20.03.2025 - 21.03.2025  \n**Wo?** ZB MED in Köln\n\n",
    "#  „ACM WSDM 2025“: renommierte Konferenz zu Websuche und Data Mining in\nHannover\n\nWissenschaftlicher Austausch und technologische Innovation im Fokus der 18.\nACM International Conference on Web Search and Data Mining\n\nDie 18. ACM International Conference on Web Search and Data Mining (WSDM 2025)\nwird vom 10.03.2025 - 14.03.2025 in Hannover stattfinden. Die WSDM zählt zu den\nführenden Konferenzen in den Bereichen Websuche, Data Mining, Maschinelles\nLernen und Künstliche Intelligenz. Sie bietet eine Plattform, auf der weltweit\nführende Wissenschaftler:innen, Fachleute und Praktiker:innen ihre neuesten\nForschungsergebnisse präsentieren und zukunftsweisende Ideen austauschen\nkönnen.\n\nDie Konferenz wird sich auf ein breites Spektrum aktueller Themen\nkonzentrieren, darunter:\n\n  * Web of Things, ortsunabhängige und mobile Datenverarbeitung (Ubiquitous and Mobile Computing) \n  * Datenschutz, Fairness, Interpretierbarkeit \n  * Soziale Netzwerke \n  * Intelligente Assistenten \n  * Crowdsourcing und menschliche Datenverarbeitung \n\n",
    "#  Infoveranstaltung für geistliche Mütter und Väter\n\n**Als Kirche wollen wir uns in die junge Generation investieren und sie\nfördern. Dazu gebraucht Gott reife geistliche Mütter und Väter.**\n\nVon **Christliches Zentrum Darmstadt**\n\n##  Datum und Uhrzeit\n\nSo. 08.12.2024 12:15 - 13:15 CET\n\n##  Veranstaltungsort\n\nChristliches Zentrum Darmstadt\n\nRöntgenstraße 18 64291 Darmstadt\n\n##  Zu diesem Event\n\n**Infoveranstaltung für geistliche Mütter und Väter**\n\nAls Kirche wollen wir uns in die junge Generation investieren und sie fördern.\nDazu gebraucht Gott reife geistliche Mütter und Väter. Wenn du im altern von\nüber 55 Jahren bist und einen Unterschied im Leben einer jungen Person machen\nmöchtest, bist du herzlich zu dieser Infoveranstaltung eingeladen.\n\nWir wollen uns gemeinsam austauschen was unsere ältere Generation auf ihrer\nReise mit Gott benötigt und welches Erbe Gott ihnen gegeben hat. Zudem\nsprechen wir über das kommende Jahr und welche Schritte wir gehen dürfen,\ndamit die junge Generation fest in Jesus verwurzelt ist.\n\nWir starten mit einem kleinen Mittagessen und laden dich herzlich ein.\n\n",
    "**HEILIGABEND | FILM-GOTTESDIENST**\n\nErlebe einen besonderen Film-Gottesdienst mit ansprechendem Programm. Es\nerwartet dich eine Atmosphäre mit weihnachtlichen Liedern und einer\nermutigenden Botschaft.\n\n**24.12.2025 um 16:00**\n\nDer Film \"Klaus\" zeigt, dass kleine Gesten der Freundlichkeit und des Gebens\neine große positive Wirkung auf die Welt haben können. Es wird deutlich, wie\nselbst ein einzelner, gutherziger Mensch eine Kettenreaktion auslösen kann,\ndie das Leben anderer verbessert und Konflikte überwindet.\n\n**Infos für Familien:  \n** Der Gottesdienst ist für die gesamte Familie geeignet und dauert ca. eine\nStunde. Es gibt kein extra Kids Programm.\n\n",
    "#  Termin für öffentliche Besichtigung\n\n07.01.2025\n\n  * Am 01.07.2025 \n  * Von 18:00 bis Uhr \n  * Tasköprüstraße 10 (ehemalige Selgros-Markthalle) \n  * Termin im Kalender speichern \n\nIn einer Informationsveranstaltung wurde bereits über die Planung zur\nErrichtung eines Notstandortes für die Unterbringung Asyl- und/oder\nSchutzsuchender in der ehemaligen Selgros-Markthalle im Bezirk Altona\ninformiert. Nun steht der Termin für die öffentliche Besichtigung fest.\n\nInformationen zum Notstandort gibt es außerdem in der Präsentation , die im\nRahmen der Informationsveranstaltung gezeigt worden ist.\n\nErgänzende Informationen zum Standort und den Terminen finden Sie auch in der\nNachbarschaftsinformation von Fördern & Wohnen (November 2024).\n\n",
    "#  Cornelia Poletto Palazzo\n\n**Wann?** 07.11.2024 - 09.03.2025  \n**Wo?** Spiegelpalast in Hamburg-Altona, Waidmannstraße 26\n\nIn diesem Jahr geht der Cornelia Poletto Palazzo bereits in die neunte\nSpielzeit in Hamburg. Neben einem neuen Menü und neuem Programm erwartet Gäste\nder Dinner-Show auch ein neuer Standort: In der Saison 2024/25 ist der\nSpiegelpalast vom 07.11.2024 - 09.03.2025 in Hamburg-Altona zu\nfinden.\n\nTickets sind hier erhältlich: **Tickets buchen**\n\n##  Das Menü von Cornelia Poletto\n\nDie Hamburger Starköchin Cornelia Poletto hat für die Dinner-Show erneut ein\nVier-Gänge-Menü entworfen. Als Vorspeise werden ein Insalata nizzarda mit\nGrenaille-Kartoffeln, Thunfisch-Tatar, Artischocke und Kräutersud gereicht.\nDen Zwischengang bildet eine grüne Minestrone mit Burratacreme, Pistazien und\nMinzöl. Als Hauptgang folgt ein „Brasato di Festa“, ein italienischer, in\nBarolo geschmorter Rinderbraten mit cremiger Polenta, Balsamico-Apfel-Rotkohl\nund Maronen. Zum Schluss wird als Dessert die „Zitronen-Jette“ serviert:\nCrostata mit Amalfizitrone, Vanillecreme und Joghurteis. Für Vegetarier*innen\nsteht ein alternatives Menü zur Verfügung.\n\n##  Das Programm: „Family Affairs“\n\nNicht nur das Menü und der Standort sind neu: Auch das Programm zeigt sich in\nneuem Gewand. Unter dem Namen „Family Affairs“ erschafft das Ensemble den\nSchauplatz einer vermeintlich gewöhnlichen Familienfeier. Eine über die ganze\nWelt verteilte, ungleiche und meist auch uneinige Verwandtschaft trifft sich\nzu einer spannungsreichen und amüsanten Zusammenkunft. In diesem Rahmen können\ndie Zuschauer*innen sich auf Akrobatik, Comedy, Slapstick und Live-Musik\nfreuen.\n\n##  Über Palazzo\n\nDer Cornelia Poletto Palazzo ist zum neunten Mal in Hamburg. Palazzo-Shows mit\nMenüs anderer Köch*innen finden in Berlin, Nürnberg, Stuttgart und Wien statt.\nDas Konzept von Zirkus- bzw. Varieté-Shows, kombiniert mit einem gehobenen\ngastronomischen Angebot in der Atmosphäre eines Spiegelpalastes geht auf den\nSchweizer Produzenten und Gründer des „Zirkus Aladin“ Ueli Hirzel zurück.\nHirzel bereiste mit seinem Zirkus ab 1981 die Schweiz. 1990 brachten Bernhard\nPaul, Hans-Peter Wodarz und Alfons Schuhbeck das Konzept nach Deutschland.\n\n",
    "#  Leonardo da Vinci in Hamburg\n\nNach dem großen Erfolg der immersiven Show Tutanchamun startete am 17.09.2024 die neue Ausstellung \"Leonardo da Vinci – uomo universale\" in\nHamburg.\n\nLeonard da Vinci - uomo universalis\n\nAlegria Exhibition GmbH\n\n##  Eine Reise durch das Leben des Genies\n\nMit einer aufwändigen immersiven Inszenierung nimmt die Ausstellung die\nBesucherinnen und Besucher mit auf eine Reise durch das Leben des Genies.\nGezeigt werden unter anderem Nachbildungen seiner zahlreichen Erfindungen und\nalle 16 Bilder, die ihm heute sicher zugeschrieben werden können. Das\nHerzstück der Ausstellung ist die immersive Inszenierung. Mittels Projektoren\nerwachen Werk und Welt des Universalgenies zu neuem Leben.\n\n**Tickets sind hier erhältlich:\n\nTickets buchen*\n\n**\n\n##  Erster unter den uomini universali\n\nLeonardo da Vinci (1452 - 1519) hatte durchaus berühmte Zeitgenossen, wie\nMichelangelo, Raffael oder Botticelli, doch niemand war so vielseitig.\n\nLeonardo war ein Universalgenie, war begnadeter Künstler, Wissenschaftler,\nIngenieur und Erfinder. Erster unter den uomini universali (Erster unter den\nUniversalmenschen)wurde Leonardo genannt. In der Renaissance beschrieb man so\ndas Idealbild eines Menschen.\n\n##  Berühmte Gemälde und Erfindungen\n\nZu Leonardos berühmtesten Gemälden zählen die _Dame mit Hermelin, Das letzte\nAbendmahl, Mona Lisa_ oder der _Vitruvianische Mensch._ Zu seinen Erfindungen\nzählen Fluggeräte, ein Helikopter, Fallschirm, mechanische Roboter, Panzer und\nvieles mehr.\n\n##  Info-Spalte\n\n##  Kontakt\n\nGaußhöfe\n\n  * Gaußstraße 190 22765 Hamburg \n\nEmpfohlene Besuchsdauer: ca. 65-75 Minuten\n\n  * +49 40 391771 \n\n  * Webauftritt aufrufen \n\n  * Kontakt speichern \n\n  * Adresse auf Karte anzeigen \n\n  * Anfahrt \n\n###  Termine\n\nTermin\n\n  01.09.2025 - 26.12.2024 \n\n###  Altersempfehlung:\n\nAltersempfehlung:\n\nAlle sind willkommen! Kinder unter 14 Jahren müssen in Begleitung ihrer\nEltern sein.\n\n###  Barrierefreiheit\n\nBarrierefreiheit\n\nDie Ausstellung ist barrierefrei.\n\nDisclaimer\n\n###  *Hinweis\n\n*Über die Einbindung dieses mit *Sternchen markierten Angebots erhalten wir beim Kauf möglicherweise eine Provision vom Händler. Die gekauften Produkte werden dadurch für Sie als Nutzerinnen und Nutzer nicht teurer. \n\n",
    "#  MJ – Das Michael Jackson Musical\n\nDas Erfolgsmusical über den Ausnahmekünstler Michael Jackson ist seit Dezember\n2024 in Hamburg zu sehen! Tickets und Hotel können Sie hier bequem online\nbuchen.\n\nBenét Monteiro als Michael Jackson in MJ – Das Michael Jackson Musical.\n\nMatthew Murphy / Stage Entertainment\n\n##  Inhaltsverzeichnis\n\n  * Tickets buchen \n\n  * Tickets und Hotel buchen \n\n  * MJ – Das Michael Jackson Musical in Hamburg \n\n  * Die Entstehung der „Dangerous“-Welttournee \n\n##  **Tickets buchen**\n\nErleben Sie das mehrfach ausgezeichnete Musical MJ – Das Michael Jackson\nMusical.\n\nTickets buchen ab 63,99€*\n\n##  **Tickets und Hotel buchen**\n\nSie möchten Ihren Musical-Besuch mit einer Reise nach Hamburg verbinden? Hier\nkönnen Sie Ihre Tickets und Hotelübernachtung im Paket buchen:\n\nReisepaket: MJ – Das Michael Jackson Musical ab 134,60€*\n\nAlle Vorteile auf einen Blick:\n\n  * Übernachtung im ausgewählten Hotel inkl. Frühstück, Zusatznächte buchbar \n  * Musical-Ticket in der gewählten Preiskategorie \n  * Hamburg Card (3 Tage) – Ihr Entdeckerticket für freie Fahrt mit Bus und Bahn im Wert von 31,90€ \n\n##  MJ – Das Michael Jackson Musical in Hamburg\n\nMit Hits wie \"Billy Jean\", \"Beat it\" oder \"Thriller\" wurde Michael Jackson\nweltberühmt. Sein künstlerisches Talent und Charisma werden in dem Broadway-\nMusical über den Entertainer gewürdigt. Das Stück erhielt vier Tony Awards,\neine Grammy Nominierung für das Cast Album und hat bereits fast eine Million\nZuschauer*innen in New York begeistert.\n\nAm 01.12.2024 feierte MJ – Das Michael Jackson Musical jetzt seine\nDeutschlandpremiere! Das Stage Theater an der Elbe ist die Bühne für das\nMusical-Spektakel über die Musiklegende Michael Jackson.\n\n##  Trailer für MJ – Das Michael Jackson Musical\n\n###  Youtube Video aktivieren\n\nMit dem Laden des Videos akzeptierst Du die\n\naktuelle Datenschutzerklärung\n\nDieses Video aktivieren\n\nZu den Datenschutz-Bestimmungen\n\n##  Die Entstehung der „Dangerous“-Welttournee\n\nRund um die Entstehungsgeschichte der 1992 er „Dangerous“-Welttournee zeigt MJ\n– Das Michael Jackson Musical einige der beliebtesten und meistverkauften\nSongs der Musikgeschichte überhaupt. Während der Proben zur Tournee nimmt\nMichael Jackson das Publikum mit auf eine Reise durch sein Leben. Das Publikum\nkann sich auf die Moves und den unverwechselbaren Sound des Stars freuen –\nerhält aber auch seltene Einblicke in den Teamgeist und die schöpferische\nKraft, die Michael Jackson zur Legende werden ließen.\n\nFür die deutsche Produktion werden die Songs von Michael Jackson im englischen\nOriginal aufgeführt, während die Dialoge ins Deutsche übersetzt sind. Für die\nBesetzung der Hauptrolle in MJ – Das Michael Jackson Musical fanden\numfangreiche Castings statt. Am Ende konnte sich Musicaldarsteller Benét\nMonteiro durchsetzen. Der gebürtige Brasilianer steht als Michael Jackson auf\nder Musicalbühne.\n\n##  Termine für MJ – Das Michael Jackson Musical\n\n##  Anfahrt\n\nMJ – Das Michael Jackson Musical | Stage Theater an der Elbe \n\n  * [Norderelbstraße 8 \n\n20457 Hamburg](#)\n\n  * Kontakt speichern \n\n  * Adresse auf Karte anzeigen \n\n  * Anfahrt \n\n###  Termine\n\nTermin\n\nPremiere am 01.12.2024\n\n",
    "#  Liedernachmittag\n\nLieder von R. Schubert, R. Franz, A. Webern, H. Wolf\n\n© MAK/LHH\n\nVortrag im Museum August Kestner\n\nMonika Abel, Sopran / Kathrin Isabelle Klein, Klavier\n\nTermine\n\n01.11.2025 ab 16:00\n\nOrt\n\nMuseum August Kestner\n\nPlatz der Menschenrechte 3\n\n30159 Hannover\n\nKonzertkarten: [email protected] und Tageskasse ab 15:00 im Museum\n\nUnter der Schirmherrschaft von Kammersängerin Helen Donath.\n\nBis zu viermal im Jahr laden wir zu einem Liedernachmittag im Museum ein.\n\nIn Zusammenarbeit mit: Lohmann-Stiftung für Liedgesang e.V., Hannover;\nFreundes- und Förderkreis des Museum August Kestner „Antike & Gegenwart e.V.“\n\n",
    "##  Die goldene Stadt\n\n**Rom im Spiegel seiner Medaillen**\n\n© MAK/LHH\n\nVortrag im Museum August Kestner\n\nMit Dr. Martin Hersch (München)\n\nIn Kooperation mit dem Freundeskreis Antike und Gegenwart\n\n**Termine**\n\n15.01.2025 ab 18:00\n\n**Ort**\n\nMuseum August Kestner\n\nPlatz der Menschenrechte 3\n\n30159 Hannover\n\n**Eintritt**\n\n5,00 €\n\n**ermäßigter Eintritt**\n\n4,00 €\n\n",
    "###\n\nVeranstaltungen\n\n#  Stadtansichten\n\n(Reise-)Geschichten zu Münzen aus Antike und Barock\n\n© Historisches Museum Hannover\n\nPostkarte Gruß aus Hannover, 1954\n\nErleben Sie bei einem Besuch der Sonderausstellung Städtetrip vielfältige und\nspannende Lyrik und Prosa verschiedener Autor*innen, nicht nur zum Thema\nReisen. Ausgewählt und vorgetragen von der Literarischen Komponistin und\nRezitatorin Marie Dettmer.\n\nTermine\n\n01.12.2025 ab 14:00-15:00\n\nOrt\n\nLandeshauptstadt Hannover\n\nTrammplatz 2\n\n30159 Hannover\n\n",
    "#  Finissage der Sonderausstellung Bartmann, Bier und Tafelzier. Steinzeug in\nder niederländischen Malerei\n\n© Museum August Kestner\n\nDiverse Krüge aus der Ausstellung\n\nMit Kuratorinnenführung\n\n**Termine**\n\n18.01.2025 ab 11:00-18:00\n\n**Ort**\n\nMuseum August Kestner\n\nPlatz der Menschenrechte 3\n\n30159 Hannover\n\n",
    "#  Nikolausmarkt\n\n##  Veranstaltungsinformationen\n\n  01.12.2024 – 08.12.2024 \n\n  2. Kulturhof \n\n© Stadt Bottrop\n\nWie in jedem Jahr organisiert das Kulturamt am zweiten Adventswochenende den\nNikolausmarkt im Kulturhof und im Umfeld des Kulturzentrums. Dabei gibt es ein\nbuntes Programm für die ganze Familie. Für die Kleinen gibt's die Möglichkeit,\nWeihnachtsgeschenke zu basteln. Das Spielmobil \"Rollmobs\" des Jugendamtes ist\nauch mit dabei und bietet jede Menge Bastel-, Back- und Nähaktionen an. In der\nLebendigen Bibliothek gibt es ein Lese- und Bastelangebot für Kinder und auch\ndie MEWA Nähstube ist hier zu finden.\n\nPrivate Kunsthandwerkerinnen und Kunsthandwerker geben einen Einblick in ihr\nSchaffen und verkaufen selbstgestalteten Schmuck, Strick- und Filzwaren. Auch\ngemeinnützige Einrichtungen sind mit von der Partie und verkaufen\nselbstgemachte Produkte. Ein Holzschnitzer aus Kirchhellen stellt zahlreiche\nHolzarbeiten aus und zeigt auch live, wie verschiedene Motive hergestellt\nwerden.\n\nIm Kulturhof wird wieder das RWW Weihnachtshaus aufgebaut, wo es heiße und\nkalte Getränke gibt. Außerdem gibt es ein weihnachtlich-gastronomisches\nAngebot auf dem Vorplatz des Kulturzentrums.\n\nDer ELE Winter-Express zieht seine Runden rund um das Kulturzentrum August\nEverding.\n\nIm B12 findet der Kunstmarkt „ARTvent“ statt, bei dem Bottroper KünstlerInnen\nihre Werke ausstellen und verkaufen.\n\nAlle kulturellen und spielerischen Angebote auf dem Nikolausmarkt sind\nkostenlos.\n\n* * *\n\n##  Programm\n\n**Der Nikolaus kommt am Freitag um 17:00!**\n\n**Filmforum:**  \nWeihnachtskino  \n\"Arthur Weihnachtsmann\"  \nSa 12.00 und 16:00, So 12:00  \nKindertheater  \nSa und So 15:00  \n**B12:** ARTvent  \n**Lebendige Bibliothek:**  \nLesungen und Basteln  \nMEWA Nähstube  \n**Kulturhof:**  \nKunsthandwerk, Sterne basteln  \n**Außerdem:** Der ELE Winter-Express  \nDas Spielmobil  \nMusikalische Walkacts  \nRiesenrad & Karussell\n\n##  Informationen\n\n| Beginn | Freitag 16:00-20:00 / Samstag 11:00-20:00 / Sonntag 11:00-18:00 | | --- | --- | \n\n##  Veranstaltungsort\n\nKulturhof\n\n##  Veranstalter\n\nKulturamt der Stadt Bottrop\n\n",
    "#  Verleihung Erlanger Theaterpreis\n\nTheater in der Garage\n\nEinmal jährlich vergibt der Förderverein den Erlanger Theaterpreis für\nherausragende künstlerische Leistungen am Schauspiel Erlangen.\n\n##  Daten\n\nSo.\n\n8.12.\n\nkeine Anmeldung nötig\n\nTheater in der Garage\n\n19:00\n\nEintritt frei\n\n##  Infos\n\nMehr Infos zum Förderverein Theater Erlangen.\n\n",
    "#  🎉 SILVESTER 2024 IM FOODKLUB 🎉\n\nFeiern Sie mit uns ins neue Jahr mit einem exquisiten levantinischen\nFestbuffet! Was Sie erwartet: • Reichhaltiges levantinisches Buffet • 48€ pro\nPerson • Erlesene Weine aus der Region • Erstklassiger fränkischer Secco •\nOptional: Champagner (auf Vorbestellung) ⚠️ Limitierte Plätze verfügbar!\nSichern Sie sich jetzt Ihren Tisch für einen unvergesslichen Jahresabschluss.\nReservierung unter: 📞 09131/9171462 📧 [email protected] Foodklub Ebrardstr.\n30, 91054 Erlangen\n\n",
    "PIANOKLÄNGE & Herzgeschichten So, 15.12.2024\n===================================================\n\nVeranstalter: Stiftung Gemeinsam für Halle\n\nWo findet diese Veranstaltung statt? Lichthaus Halle  \nDreyhauptstraße 3  \n06108 Halle (Saale)\n\nWann findet diese Veranstaltung statt? So, 15.12.2024\n\nBeginn: 15:00\n\nEinlass: 14:30\n\nZum Kalender hinzufügen\n\n###  Tickets\n\n####  Ticket (Vorverkauf)\n\nAktuell verfügbar: 21\n\n18,00 € inkl. 7% MwSt.\n\n\\-\n\n\\+\n\nZur Kasse\n\n",

]

# texts = TEXTS


# 1️⃣ Punkt als Suffix & Infix definieren (damit er zwischen Zahlen trennt)
suffixes = list(nlp.Defaults.suffixes) + [r"\."]  +[r"\,"] # Punkt als Suffix hinzufügen
infixes = list(nlp.Defaults.infixes) + [r"(?<=\d)\.(?=\d)"] + [r"(?<=\d)\:(?=\d)"]  # Punkt zwischen Zahlen trennen


# Regex-Objekte kompilieren
suffix_re = compile_suffix_regex(suffixes)
infix_re = compile_infix_regex(infixes)

# Angepasste Tokenizer-Funktion setzen
nlp.tokenizer = Tokenizer(nlp.vocab, suffix_search=suffix_re.search, infix_finditer=infix_re.finditer)
# 2️⃣ Entity Ruler für Datumsangaben hinzufügen
ruler = nlp.add_pipe("entity_ruler")

patterns = [
    {
        "label": "DATE",
        "pattern": [
            {"SHAPE": "dd"}, {"ORTH": "."}, {"SHAPE": "dd"}, {"ORTH": "."}, {"SHAPE": "dddd"}
        ]
    },
    {
        "label": "TIME",
        "pattern": [
            {"SHAPE": "dd"}, {"ORTH": ":"}, {"SHAPE": "dd"}
        ]
    }
]

ruler.add_patterns(patterns)

for text in texts:

    analyzer = MarkdownAnalyzer(text)
    md_elements = analyzer.identify_all().get("block_elements")
    for element in md_elements:
        text = element.text
        text = normalize_data(text)
        replacements = {" und ": " + ", " bis ": " - ", " um ": " ", " ab ": " "}
        for old, new in replacements.items():
            text = text.replace(old, new)
        # text = remove_stopwords(text)
        doc = nlp(text)
        for sent in doc.sents:
            doc_small = nlp(sent.text)
            if doc_small.ents:
                print("*"*100)
                print(doc_small.text)


                tokens_between_entities = extract_tokens_between_entities(doc_small)
                # Ausgabe

                sequence = [Token(text=doc_small[:doc_small.ents[0].start].text)]
                entities = list(doc_small.ents)
                # entities = [Entity(e.text, e.label_) for e in doc_small.ents]
                sequence.append(entities[0])
                print("Entitäten: ", entities)
                for i, tokens in enumerate(tokens_between_entities):
                    connector = tokens.text.strip()
                    if len(connector) > 1:
                        sequence.extend([Token(text=c) for c in connector.split(",")])
                    else:
                        sequence.append(Token(connector))
                    sequence.append(entities[i+1])
                sequence.append(Token(doc_small[doc_small.ents[len(entities)-1].end:].text))

                # Beispiel:
                strong_relations = find_strong_relations(sequence)
                print("Strong relations: ", strong_relations)
                sequence = [e.text for e in sequence]
                print("Sequences: ", sequence)

                final_relations = []
                remaining_sequence = sequence[:]  # Eine Kopie von `sequence` behalten

                for relation in strong_relations:
                    relation_texts = [r.text for r in relation]  # Entitäten in Text konvertieren
                    complete_group = []

                    for r in relation_texts:
                        if r in remaining_sequence:
                            i = remaining_sequence.index(r)  # Index in der verbleibenden Liste finden
                            s = remaining_sequence[:i]  # Alles davor nehmen
                            complete_group.extend(s)  # In die aktuelle Gruppe packen
                            complete_group.append(r)  # Das aktuelle `r` hinzufügen
                            remaining_sequence = remaining_sequence[i + 1:]  # Kürze die Liste ab
                        else:
                            print(f"Warnung: '{r}' nicht in der verbleibenden Sequence gefunden!")

                    final_relations.append(complete_group)

                # Ausgabe der finalen Gruppen
                print("Final Relations: ", final_relations)
                for relation in final_relations:
                    print("Relation: ", " ".join(relation))
                print("*" * 100)