Laden...

[erledigt] Regex Pattern, der auf einen bestimmen Teil eines anderen Patterns als Input matcht

Erstellt von bredator vor 12 Jahren Letzter Beitrag vor 12 Jahren 765 Views
B
bredator Themenstarter:in
357 Beiträge seit 2010
vor 12 Jahren
[erledigt] Regex Pattern, der auf einen bestimmen Teil eines anderen Patterns als Input matcht

Ich habe vorgegeben, das Ergebnis einer OCR-Operation. Um bessere Ergebnisse bei der anschließenden SQL-Suche zu erhalten, werden bei der OCR auch die ersten beiden Alternativ-Chars ausgewertet. Außer bei N, M und H, welche automatisch bei einem der drei erkannten mit eingefügt werden. Dadurch ergeben sich Texte wie folgender:

[HNMRK][aeo][li1][li1][oO0] [WMK][eao][li1][til] [wmx][il1][eao][g9q][til] [53S][0GD][NHMN][G6Q]
(Hallo Welt wiegt 50 mg steht auf dem gescannten Papier, das kann jeder lesen, aber die CPU halt nicht. Drum sollen hier Mustererkennungen durchgeführt werden, um den String entsprechend zu verarbeiten, je nach seinem Inhalt)

Nun soll ich den Text zerpflücken und anhand von SQL Daten möglichst genau herausfinden, was dort steht. Ein wichtiger Teil ist dabei die Gewichtsangabe. Diese kann entweder am Ende oder sonstwo stehen, kann also nicht fest bestimmt werden. Gemein haben sie allerdings, dass sie aus einer Zahl und einer Größe bestehen (meist mg). Nun hatte ich zuerst die Idee, mittels Regex dieses "mg" zu erkennen und damit auf den Block loszugehen, in dem dieses erkannt wurde. Klar, es kann Fälle geben, wo dieses "mg" auch woanders erkannt werden würde, das kann man mit anschließender Zahlprüfung aber dann schnell wieder verwerfen. Das Problem habe ich nun dabei, dass ich nicht weiß, wie ein entsprechender Regex-Ausdruck hier aussehen sollte. Die Blöcke in den Klammern sind leider nicht immer 3 oder 4 Zeichen lang (es können auch mal 2 oder 5 oder sogar mehr sein). Zudem können auch Zahlen drin stehen (wurde halt als Alternativ-Char der OCR geliefert).

Mein Audruck sieht bisher so aus: [[m|M|\D]{3}][[g|G|\w]{3}]

Fehler hierbei sind natürlich:

  • Längen auf 3 festlegen geht nicht
  • m oder M muss im ersten Klammerblock vorkommen, an irgendeiner Stelle, ebenso g oder G im zweiten Block
  • die übrigen Zeichen des Blocks können beliebige sein (ich habe nur \D im ersten gewählt, weil Zahlen eher
    selten hier als Alternative kommen... )

Alles in Allem bin ich gerade an einem Punkt, wo das Hirn beschlossen hat, erst mal eine größere Kaffeepause zu machen und auf irgendeine Eingebung oder einen Schubser zu warten. Wäre schön, wenn hier jemand so einen Schubser geben könnte 😉

Grüße

A
764 Beiträge seit 2007
vor 12 Jahren

Hallo bredator,

Hotte hat uns freundlicherweise das RegEx Studio zur Verfügung gestellt (das mir schon gute Dienste geleistet hat).

In deinem Fall würde ich jetzt einige möglichst markante Strings nehmen und versuchen einen gemeinsamen Nenner zu finden, damit du erst mal die nötigen Rahmenbedingungen hast. Die sollten dann feststehen und die kannst du dann ja nochmal posten.

Eventuell hilft dir auch noch das [Artikel] Regex-Tutorial

Gruß, Alf

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo bredator,

du willst also wissen, welcher Teil in dem Ausgangspattern

[HNMRK][aeo][li1][li1][oO0] [WMK][eao][li1][til] [wmx][il1][eao][g9q][til] [53S][0GD][NHMN][G6Q]

case-insensitive auf 50mg bzw. \d+mg matchen würde? Nehmen wir doch erstmal ein einzelnes Zeichen. Welcher Teil des Ausgangspattern würde auf m matchen? Das ist doch einfach: Der Teil, der mit [ beginnt und mit ] endet und in dem dazwischen (mindestens) ein m steht, also [.m.]. Ok, man muss noch verhindern, dass .* auf eckige Klammern matcht, weshalb man .* beide Male durch [^[]]* ersetzt. Was man für m gemacht hat, kann man auch für alle anderen Zeichen(klassen) 5 und 0 oder \d sowie g machen und muss die einzelnen Teilpattern nur hintereinander schreiben. Fertig.

Damit kannst du allerdings nicht unbedingt zuverlässig das Problem lösen, ob mit [G6][O0][m][g] 0mg oder 60mg gemeint sind, oder ob mit [A]++[S5][G][A]**[E] wirklich 5g gemeint sind.

herbivore

B
bredator Themenstarter:in
357 Beiträge seit 2010
vor 12 Jahren

Hallo nochmal,

danke für die Hilfe. Ich habe allerdings von Anfang an einen Denkfehler gemacht, da ja die Ausgabe meiner OCR im Prinzip schon mein regulärer Ausdruck ist den ich nun nur noch gegen mögliche gültige Werte matchen muss. Diese möglichen Werte kann ich durch eine Datenbankabfrage, die vorher schon entsprechend vorbereitet wurde, machen. Dadurch habe ich jetzt genau das erreicht, was ich haben wollte und bisherige Tests versprechen da recht viel.

Danke auch für die Anmerkungen von herbivore. Werde mir das im Hinterkopf behalten, falls doch mal Probleme auftreten sollten. Bin momentan jedenfalls begeistert 😄 Nicht zuletzt, weil ich in letzter Zeit reguläre Ausdrücke als sehr mächtiges Werkzeug kennengelernt habe und ich mich eigentlich lange dagegen gesträubt habe.

Danke nochmal 😉