Page 1 of 2

Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 06:01
by LuckyJoe
Hallo zusammen,

ich verwende zur Identifizierung von Veranstaltungen (Trainings) ein Kürzel, das sich wie folgt zusammensetzt:
"yy-mm-dd (XX) nnnnn Ort"
- Die ersten 8 Zeichen sind dabei immer das Datum: Jahr-Monat-Tag (alle Angaben IMMER 2-stelig)
- Leerzeichen
- zwei Buchstaben in einer Klammer: "(KT)" oder "(TT)" usw. (abschließende Aufzählung s.u.)
- Leerzeichen
- 5 Ziffern (dt. Postleitzahl)
- Leerzeichen
- (deutscher) Ortsname

Nach diesem Schema werden dann auch dazugehörige Ordner und Dateinamen verwendet, z.B.: "20-05-15 (KT) 50996 Köln". Wenn ich also dieses Kürzel habe, dann kann ich z.B. die dazugehörige Teilnehmerliste aufrufen.

Ich möchte nun ein solches Kürzel in einem String suchen und "extrahieren":
Markiere ich also z.B. den Betreff einer E-Mail, der "RE: meine Anmeldung zu [20-05-15 (KT) 50996 Köln]" lautet, dann soll mein Script mir das gesuchte Kürzel auf Tastendruck ins Clipboard schreiben.
Das Kürzel kann dabei irgendwo innerhalb der Markierung stehen (Anfang, Mitte, Ende). Es kann durch "[]" eingerahmt sein, muss es aber nicht. Es wird beendet mit einem " - " oder wie erwähnt mit "]" oder dadurch, dass es am Ende des Strings steht.

Den Anfang meines Scriptes habe ich schon:

Code: Select all

MyAuswahl := "20-05-15 (KT) 50996 Köln - Anmeldung: [email protected]"
RegExMatch(MyAuswahl, "[1-4][0-9]-[0-1][0-9]-[0-3][0-9] \((KT|KA|TT|JT|FT|ET|DT)\) [0-9]{5} ", Kuerzel)
MsgBox, % Kuerzel
Damit bekomme ich das Kürzel bis zur PLZ und dem nächsten Leerzeichen.
Wie finde ich auch noch die Ortsbezeichnung? Wobei zu beachten ist, dass ein Leerzeichen nicht unbedingt den Ortsnamen beendet, wie z.B. bei
"RE: 20-08-21 (KT) 63628 Bad Soden-Salmünster - Anmeldung: Hans.Pumpelmuser at abcdef.de"
... soll herauskommen: "20-08-21 (KT) 63628 Bad Soden-Salmünster"

Danke schon mal für's Lesen.

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 06:44
by haichen
Das "- Anmeldung" kommt wahrscheinlich auch nicht immer vor?

Edit: Habs jetzt richtig gelesen :-)

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 07:01
by haichen
Mal ein Versuch (war ja schon fast fertig):

Code: Select all

MyAuswahl := "20-05-15 (KT) 63628 Bad Soden-Salmünster - Anmeldung: Hans.Pumpelmuser at abcdef.de"
;MyAuswahl := "RE: meine Anmeldung zu [20-05-15 (KT) 63628 Bad Soden-Salmünster] "
RegExMatch(MyAuswahl, "\[?([1-4][0-9]-[0-1][0-9]-[0-3][0-9] \((KT|KA|TT|JT|FT|ET|DT)\) [0-9]{5}\s+\w.*)(\s-|\])", Kuerzel)
MsgBox, % Kuerzel1

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 07:42
by LuckyJoe
Hallo haichen,

Danke schon mal, klappt "fast". Die eckigen Klammern sollen nicht mit ausgegeben werden, sondern nur das Kürzel. Ich kann das später mit "StrReplace" rausnehmen. Somit kann ich deinen Ausdruck aber schon etwas verkürzen:

Code: Select all

RegExMatch(MyAuswahl, "[1-4][0-9]-[0-1][0-9]-[0-3][0-9] \((KT|KA|TT|JT|FT|ET|DT)\) [0-9]{5} .*(\s-|])", Kuerzel)
Allerdings findet er das Kürzel nicht, wenn es am Ende des Strings steht:
MyAuswahl := "RE: meine Anmeldung zu 20-05-15 (KT) 63628 Bad Soden-Salmünster"

Wie kann ich das prüfen?

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 07:53
by haichen
"Die eckigen Klammern sollen nicht mit ausgegeben werden, sondern nur das Kürzel. "
MsgBox, % Kuerzel1

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 07:59
by haichen
Du könntest die Mustererkennung dafür einfach weglassen:

Code: Select all

MyAuswahl := "20-05-15 (KT) 63628 Bad Soden-Salmünster (KT) - Anmeldung: Hans.Pumpelmuser at abcdef.de"
MyAuswahl := "RE: meine Anmeldung zu [20-05-15 (KT) 63628 Bad Soden-Salmünster (KT)] "
RegExMatch(MyAuswahl, "\[?([1-4][0-9]-[0-1][0-9]-[0-3][0-9].+ [0-9]{5}\s+\w.*)(\s-|\])", Kuerzel)
MsgBox, % Kuerzel1

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 08:10
by haichen
Der Trick ist, die Eingrenzung gut zu setzen. Also ich habe jetzt Datum und " -" (Leerzeichen und Bindestrich) oder "[" und "]" genommen.
Dazu wird mit den ersten beiden runden Klammern "\[?([1-4][0-9]-[0-1][0-9]-[0-3][0-9].+ [0-9]{5}\s+\w.*)(\s-|\])" der Subpattern angezeigt (Kuerzel1). Also ohne die eckigen Klammern.

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 08:21
by LuckyJoe
Danke für deine Unterstützung und auch die Erklärung.
MsgBox, % Kuerzel1
... hatte gedacht, du hast dich vertippt :lol:

Ok, wieder etwas schlauer, aber es ist immer noch nicht das, was ich suche:
Zunächst sollte die Klammeraufzählung "\(KT|KA|TT|JT|FT|ET|DT\)" drin bleiben (ist abschließend).

Mein "Kuerzel" soll auch dann erkannt werden, wenn hinter der Stadt keine Zeichen mehr kommen, also wie bei
MyAuswahl := "Re: 20-08-21 (TT) 63628 Bad Soden-Salmünster"
Gewünschtes Ergebnis: "20-08-21 (TT) 63628 Bad Soden-Salmünster"
Das findet er bei den Ausdrücken von dir und mir noch nicht. Hast du noch eine Idee?

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 08:32
by haichen
Ich versuchs mal das aufzudröseln:

\[? Am Anfang steht eine eckige Klammer oder auch nicht

([1-4][0-9]-[0-1][0-9]-[0-3][0-9].+ [0-9]{5}\s+\w.*)
Was in den runden Klammern gefunden wird, ist der Subpattern der in Kuerzel1 (nicht die 1 vergessen) gespeichert wird.
Es wird ein Datum gesucht, gefolgt von beliebigen Zeichen (.+), der 5stelligen Posleitzahl ([0-9]{5}), mindestens einem Leerzeichen (\s+) und einem Wort (\w) und weiteren Zeichen (.*)

(\s-|\])
fertig ist das Muster wenn ein Leerzeichen und Bindestrich auftauchen oder die schließende eckige Klammer.

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 08:35
by haichen
Da fehlte noch das Zeilenende $ als Begrenzer

Code: Select all

MyAuswahl := "Re: 20-08-21 (TT) 63628 Bad Soden-Salmünster"
RegExMatch(MyAuswahl, "\[?([1-4][0-9]-[0-1][0-9]-[0-3][0-9].+ [0-9]{5}\s+\w.*)(\s-|\]|$)", Kuerzel)
MsgBox, % Kuerzel1

Re: Teil-String aus String extrahieren (RegEx)

Posted: 07 Jul 2020, 08:37
by haichen
Bekomme ich nicht hin. Hab einen Klemmer. Mal drüber schlafen. Sorry.

Re: Teil-String aus String extrahieren (RegEx)  Topic is solved

Posted: 08 Jul 2020, 02:25
by haichen

Code: Select all

MyAuswahl1 := " hhh 20-05-15 (KT) 63628 Bad Soden-Salmünster (KT) - Anmeldung: Hans.Pumpelmuser at abcdef.de"
MyAuswahl2 := "RE: meine Anmeldung zu [20-05-15 (KT) 63628 Bad Soden-Salmünster (KT)    ]   "
MyAuswahl3 := "          Re: 20-08-21 (TT) 63628 Bad Soden-Salmünster      "
text:=""

r:="U)\[?([1-4][0-9]-[0-1][0-9]-[0-3][0-9].+[0-9]{5}\s+\w.*)(\s-|\]|$)"

loop,3 
{
RegExMatch(MyAuswahl%a_index%, r, Kuerzel)
text.= "MyAuswahl" a_index "`n|" Kuerzel1 "|`n`n"
}
MsgBox, % text

/* Resultat
MyAuswahl1
|20-05-15 (KT) 63628 Bad Soden-Salmünster (KT)|

MyAuswahl2
|20-05-15 (KT) 63628 Bad Soden-Salmünster (KT)    |

MyAuswahl3
|20-08-21 (TT) 63628 Bad Soden-Salmünster      |
*/
Ich wollte den regulären Ausdruck eigentlich anders formulieren. So funktioniert es. Ohne das U) "ungreedy" wäre das Musterende immer das Zeilenende ($). Mit U bricht ist das Muster mit dem ersten Fund von "Leerzeichen Bindestrich \s-" oder "schließende eckige Klammer \]" oder "Zeilenende $" ab. Ich hoff die Erklärung ist soweit richtig. :roll:

Re: Teil-String aus String extrahieren (RegEx)

Posted: 08 Jul 2020, 02:48
by LuckyJoe
Hallo haichen,
:bravo:
das ist SUPER! Läuft mit allen derzeit durchgespielten Beispielen. Auch deine Erklärung mit dem "U" ist verständlich - Danke für deine Mühen.

Re: Teil-String aus String extrahieren (RegEx)

Posted: 08 Jul 2020, 06:24
by just me
Hallo Lucky Joe,

der Zug ist zwar schon abgefahren, aber mich irritiert trotzdem etwas.
Nach diesem Schema werden dann auch dazugehörige Ordner und Dateinamen verwendet, z.B.: "20-05-15 (KT) 50996 Köln".
Da stellt mich mir die Frage, wozu Du den Ortsnamen überhaupt brauchst. Kan es denn für 20-05-15 (KT) 50996 überhaupt mehrere Ordner/Dateien mit unterschiedlichen Ortsnamen geben?

Re: Teil-String aus String extrahieren (RegEx)

Posted: 08 Jul 2020, 06:37
by LuckyJoe
Hallo just me,

du hast vollkommen Recht, die Angabe des Ortes ist eigentlich überflüssig, da die PLZ eindeutig ist. Ich (und mein Team) haben durch die Ortsangabe aber einen besseren Überblick, da es mühseliger ist, Nummern gedanklich zu "übersetzen", als den Ortsnamen im Pfad-/Dateinamen mitzuführen. Vor allem bei einer schnellen Suche nach "Hintertupfingen" ist das einfacher, als zunächst die PLZ dazu herauszusuchen.
Das Script dient dazu, vor allen beim E-Mail-Verkehr durch Markieren des Betreffs (Doppelklick ist schneller, als das gewünschte Kürzel dort mit der Maus fummelig zu markieren) das Kürzel herauszufiltern und dann z.B. die Teilnehmerliste zu laden oder in den Ordner zu springen.

Danke trotzdem für den Hinweis - ich bin für Kürzungen beim Scripten immer dankbar.

Re: Teil-String aus String extrahieren (RegEx)

Posted: 08 Jul 2020, 07:18
by haichen
Ich weiß nicht wie diese Daten entstehen ob durch Software, Webseite oder Handarbeit (eintippen). Bei letzterem ist es vermutlich sowieso sinnvoll PLZ und Ortsname zu haben um hier Falscheingaben zu erkennen. Ein Zahlendreher ist schnell produziert. Ein Fehler in Ortsname UND PLZ läßt sich händisch leicht korrigieren. Aber ich hatte mir auch erst gedacht, das die PLZ ausreicht.

Re: Teil-String aus String extrahieren (RegEx)

Posted: 08 Jul 2020, 07:44
by LuckyJoe
... hat sich seit 16 Jahren (fehlerlos) bewährt ;-)

Re: Teil-String aus String extrahieren (RegEx)

Posted: 08 Jul 2020, 07:47
by just me
Die Frage lautet ja: Was machst Du mit dem extrahierten Text. Wenn es darum geht, einen Ordner oder eine Datei mit gleichem Namensschema zu finden, sollte ja ein

Code: Select all

SuchOrdner := "..."
Loop, Files, %Suchordner%\%NameAusRegEx%*
{
	FilePath := A_LoopFilePath
	Break
}
ausreichen.

Re: Teil-String aus String extrahieren (RegEx)

Posted: 08 Jul 2020, 10:02
by LuckyJoe
... ah, jetzt weiß ich, worauf du hinaus willst: damit mache ich die RegEx-Suche nicht ganz so kompliziert - genial! Baue ich noch mit ein. Danke!

Re: Teil-String aus String extrahieren (RegEx)

Posted: 08 Jul 2020, 10:06
by BoBo
Das Kürzel kann dabei irgendwo innerhalb der Markierung stehen (Anfang, Mitte, Ende). Es kann durch "[]" eingerahmt sein, muss es aber nicht. Es wird beendet mit einem " - " oder wie erwähnt mit "]" oder dadurch, dass es am Ende des Strings steht.
Well, nach Beantwortung von just-me's Frage noch eine von mir: warum lässt du dir 16 Jahre lang Daten mit derartigen Varianzen aufs Auge drücken? :o :think: :silent:

Wenn es redundante Vorgänge sind, sollte sich doch problemlos eine Dateinamenspezifikation etablieren* lassen ( :arrow: weisungsbefugter Teamleader)?
Nach dreimal freundlichem Retournieren hat das selbst bei unseren Kunden immer geklappt, und nach 3 Wochen wusste keiner mehr das es je anders war.
Stichworte wie 'Performancesteigerung/Vereinfachung/Automatisierung/...' sind auch da durchaus akzeptable Argumentationshilfen. Anyway ... 8-)

* wenn das mal kein Anlaß ist ein AHK-gadget zu spenden, welches spezifikationskonforme Dateinamen ausspuckt ;)