String Vergleich mit re.search()

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
KuniBert
User
Beiträge: 11
Registriert: Mittwoch 4. März 2015, 19:41

Hallo,

ich bin ein totaler Neuling im Programmieren. Jetzt habe ich ein Projekt für die Uni mit einem Raspberry Pi.
Ich habe mich für ein Schrankensteuerung entschlossen die mit Hilfe der Pi Kamera ein Bild vom Kennzeichen macht
und dieses dann Vergleicht mit Kennzeichen aus einer txt Datei.
Was ich bisher hin bekommen habe ist das aufnehmen, bearbeiten und umwandeln in tiff und das auslesen
über tesseract.
Jetzt habe ich das Problem, dass ich mein String von Tesseract irgendwie nicht bei re.search() verarbeitet bekomme.
Sitze schon eine weile dran und verzweifle langsam.
Mein Code sieht an der Stelle so aus:

Code: Alles auswählen

from PIL import Image
from pytesser import *

KennzeichenDatenbank = open("KeinzeichenDaten.txt" , "r" )
KennzeichenDB = KennzeichenDatenbank.read()
KennzeichenDatenbank.close()

image_file = 'Test3.tif'
im = Image.open(image_file)
KennzeichenREAD = image_to_string(im)

if re.search(KennzeichenREAD , KennzeichenDB):
 print "yes"
else:
 print "no"
Wenn ich zwischendurch mal print KennzeichenREAD , KennzeichenDB einfüge gibt er mir ha genau die gleichen Strings aus,
jedoch ist mein re.search() immer "no". Wenn ich re.search() den String manuell vorgebe, dann klappt es.
Ich weiß nicht mehr weiter, bitte helft mir!!!

Danke im vorraus!!!
Sirius3
User
Beiträge: 18265
Registriert: Sonntag 21. Oktober 2012, 17:20

@KuniBert: wenn Du prüfen willst, ob ein String in einem anderen enthalten ist, gibt es das "in"-Keyword. Reguläre Ausdrücke haben Zeichen mit spezieller Bedeutung, und für Deinen Fall sind sie ja gar nicht nötig.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du solltest Dich auch mehr an PEP8 halten. Also vier Leerzeichen einrücken pro Ebene und Namen nicht mit Großbuchstaben benennen usw.

Unabhängig zum Hinweis von Sirius3, dass Du evtl. gar keine regulären Ausdrücke brauchst, solltest Du solche Probleme in einer Python-Shell *direkt* austesten. Damit kannst Du dann *ein* Kennzeichen und *ein* gegebenes aus der Datenbank konkret untersuchen und experiemtieren, *wie* Du eine Gleichheit feststellen kannst. Dazu blendest Du Bild in Text wandeln und IO-Zugriffe komplett aus! :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@KuniBert: Erstmal brauchst Du dafür keinen regulären Ausdruck, eine Zeichenkette in einer anderen suchen geht einfacher mit dem ``in``-Operator:

Code: Alles auswählen

In [1]: 'pa' in 'spam'
Out[1]: True

In [2]: 'rot' in 'spam'
Out[2]: False
Wenn Du genau wissen willst was Deine Werte enthalten, dann lass Dir mal den Typ ausgeben, den bekommt man mit der `type()`-Funktion, und dann die `repr()`-Darstellung statt der Zeichenkette. Bestimmte Zeichen siehst Du sonst nämlich nicht oder man übersieht sie zu leicht. Zum Beispiel Leerzeichen am Ende einer Zeichenkette oder so Sachen wie Nullbytes und andere Bytewerte die in der Ausgabe oft überhaupt nicht sichtbar sind.
KuniBert
User
Beiträge: 11
Registriert: Mittwoch 4. März 2015, 19:41

Danke für eure schnellen Antworten!
Ich werde mir das mit - in mal anschauen. Die Kennzeichen werden so aussehen "B-KS 8385".
Meint ihr da gibt es dann Probleme ohne reguläre ausdrücke?

Danke auch für die Hinweise der Formatierung!
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Je nach Groesse deiner "Datenbank" wirst du mit dem Ansatz Probleme bekommen. Solange du nur komplette Treffer finden willst, solltest du deine Datenbank in ein Set umwandeln und dort auf Mitgliedschaft pruefen.

Du wirst aber keine Probleme bekommen nur weil du keine RE benutzt.
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

KuniBert hat geschrieben:Meint ihr da gibt es dann Probleme ohne reguläre ausdrücke?
Ohne reguläre Ausdrücke wird es schneller sein. Das sollte eigentlich kein Problem darstellen.
Sirius3
User
Beiträge: 18265
Registriert: Sonntag 21. Oktober 2012, 17:20

@/me: die Kaffee-Industrie wird da anderer Meinung sein :P
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Sirius3 hat geschrieben:@/me: die Kaffee-Industrie wird da anderer Meinung sein :P
Und was ist mit Tee? :twisted:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Hyperion hat geschrieben:Und was ist mit Tee? :twisted:
Wen interessiert schon gefärbtes Wasser? :wink:
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

/me hat geschrieben: Wen interessiert schon gefärbtes Wasser? :wink:
Mich :twisted:

Außerdem: Hast Du als Kind nie dieses schöne bunte Wassereis gegessen? :mrgreen:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Wieso nur als Kind? Ich mag die immer noch. :-)

@/me: Kaffee ist doch auch nur gefärbtes Wasser. Die Farbe ist halt ein bisschen kräftiger. :-P
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

@BlackJack: Ich nicht mehr - aber meine Freundin... daher ist im Sommer unser Gefrierfach immer voll von diesen Dingern (und der Kühlschrank mit Grillkäse :mrgreen: )

@Kaffee vs Tee: Tee kann auch kräftige Farben entwickeln... insbesondere, wenn man beim Proggen vergisst den Filter herauszunehmen... (Ich vermisse mein ``KTeaTime`` unter Windows :( )
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
BlackJack

@Hyperion: Ich dachte KDE bekommt man auch unter Windows zum laufen? Ausserdem liesse sich so ein Timer doch leicht in Python selber programmieren. :-)

Ansonsten werfe ich noch mal Mate-Tee in die Runde. O-Ton von einem Kollegen: „Schmeckt wie Aschenbecher.”. Egal, ich mags. :-)
Benutzeravatar
snafu
User
Beiträge: 6862
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

BlackJack hat geschrieben:Ansonsten werfe ich noch mal Mate-Tee in die Runde. O-Ton von einem Kollegen: „Schmeckt wie Aschenbecher.”. Egal, ich mags. :-)
Mate-Tee ist super. Ich kenne es zumindest in Form von Club Mate. Mein Favorit: Club Mate Ice-T. Schmeckt IMHO besser als normales Club Mate und hat noch ein bißchen mehr Koffein. :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

BlackJack hat geschrieben:@Hyperion: Ich dachte KDE bekommt man auch unter Windows zum laufen? Ausserdem liesse sich so ein Timer doch leicht in Python selber programmieren. :-)
Ich habe das noch nie probiert - in meiner Freizeit rühre ich Windows aber auch selten an. Aber tatsächlich habe ich damit schon mal geliebäugelt, einen solchen selber zu timen :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
KuniBert
User
Beiträge: 11
Registriert: Mittwoch 4. März 2015, 19:41

BlackJack hat geschrieben:@KuniBert: Erstmal brauchst Du dafür keinen regulären Ausdruck, eine Zeichenkette in einer anderen suchen geht einfacher mit dem ``in``-Operator:

Code: Alles auswählen

In [1]: 'pa' in 'spam'
Out[1]: True

In [2]: 'rot' in 'spam'
Out[2]: False
Wenn Du genau wissen willst was Deine Werte enthalten, dann lass Dir mal den Typ ausgeben, den bekommt man mit der `type()`-Funktion, und dann die `repr()`-Darstellung statt der Zeichenkette. Bestimmte Zeichen siehst Du sonst nämlich nicht oder man übersieht sie zu leicht. Zum Beispiel Leerzeichen am Ende einer Zeichenkette oder so Sachen wie Nullbytes und andere Bytewerte die in der Ausgabe oft überhaupt nicht sichtbar sind.

Ich habe die `repr()`-Darstellung mir ausgeben lassen ´. Die Ergebnisse sehen wie folgt aus:
aus ocr: ' B-KS 8583\n\n '
aus txt: ' B-KS 8583\n '
also unterschiedlich? Was bedeuten hier die \n und wie bekomme ich die Beiden gleich?
Ich habe auch nichts weiter über den ``in``-Operator gefunden. Wie würde da ein Code aussehen? so?

Code: Alles auswählen

if a in b:
    print "yes"
else:
    print "no"
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

KuniBert hat geschrieben: Ich habe die `repr()`-Darstellung mir ausgeben lassen ´. Die Ergebnisse sehen wie folgt aus:
aus ocr: ' B-KS 8583\n\n '
aus txt: ' B-KS 8583\n '
also unterschiedlich? Was bedeuten hier die \n und wie bekomme ich die Beiden gleich?
Das ist die Repräsentation des Zeilenumbruchs (bei Unixoiden Systemen). Probiere es doch aus! BlackJack hat Dir das doch schon gezeigt. Öffne eine Python-Shell Deiner Wahl und tippe das dort mal ein :-)

Ich würde diese Whitspaces jedoch vor irgend welchen Vergleichen entfernen. Dafür gibt es die ``strip``-Methode auf Strings.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
KuniBert
User
Beiträge: 11
Registriert: Mittwoch 4. März 2015, 19:41

So hat es funktioniert. Ist das ok?

Code: Alles auswählen

a = ocr.replace('\n',"")
b = kenndb.replace('\n',"")

if a in b:
    print "yes"
else:
    print "no"

OUT: yes
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

KuniBert hat geschrieben:So hat es funktioniert. Ist das ok?
Nein! (Weil das total ineffizient ist!) Ich hatte Dir doch schon ``strip`` genannt. Außerdem werden damit auch andere und vor allem führende Whitespaces entfernt.

Und Du hast es vermutlich wieder nicht in einer Shell probiert - denn das ist ja trivial und erfordert keinen komplizierten ``if...else``-Ausdruck:

Code: Alles auswählen

scanned =  ' B-KS 8583\n\n '.strip()
given = ' B-KS 8583\n '.strip()
scanned in given
> True
Im ürbigen würde man das ``strip`` bereits beim Lesen aus der Textdatei ausführen und nicht *jedes* Mal unmittelbar vor dem Vergleich.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Antworten