Wie und womit suchen ?

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.
Antworten
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Hallo zusammen?

Gesucht werden soll z. Bsp. nach diesem String:
"v5-3-7+6"

Als Ergebnis soll aber auch alle Möglichkeiten gelten, die die gleichen Zeichen nach den ersten zwei verwenden, aber in anderer Reihenfolgen. Also auch z. Bsp

"v5-3+6-7" oder "v5-7-3+6" usw.

@edit:

Sorry, das mit den ersten 2 Zeichen ist Semmel, es gehören aber immer v und nachstehende Zahl sowie - und + und nachstehende Zahl zusammen ein richtiges Ergebnis wäre also auch:

"-3v5+6-7"

Vielen Dank im Voraus,

rolgal_reloaded
BlackJack

Das suchen selbst könnte man mit einem regulären Ausdruck erledigen. Zum Beispiel nach dem Muster: eins der drei Zeichen 'v', '+', '-' gefolgt von einer Ziffer und das 4 mal hintereinander oder im Klartext r'([v+-]\d){4}' :-)

Die Treffer kann man dann "normalisieren" und mit dem "normalisierten" Suchwort vergleichen.

Code: Alles auswählen

def normalize(string):
    return ''.join(sorted(string[i:i+2] for i in xrange(0, len(string), 2)))


def main():
    strings = ('v5-3-7+6', 'v5-3+6-7', 'v5-7-3+6', '-3v5+6-7')
    for string in strings:
        print normalize(string)
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Ich habs auch mit einer regex versucht (wenn die Länge fix sein soll, ist Blackjack's Ding wohl besser):

Code: Alles auswählen

pattern = re.compile(r"^(?:[v+-]\d)+$")

if pattern.match("-3v5+6-7"): print ok
PS: Es funktioniert nicht, wenn ich statt [v+-] ... [+-v] nehme. Warum?

PPS: Mit Ding meinte ich seine regex :)
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

BlackJack hat geschrieben:Das suchen selbst könnte man mit einem regulären Ausdruck erledigen. Zum Beispiel nach dem Muster: eins der drei Zeichen 'v', '+', '-' gefolgt von einer Ziffer und das 4 mal hintereinander oder im Klartext r'([v+-]\d){4}' :-)
Die Länge kann aber unterschiedlich sein, so könnte sein, dass ich ein anderes mal das hier suche:

"-2-3+6"

Womit wir beim nächsten wären: v,+ oder - müssen nicht immer alle vorkommen.
Sorry mir wird es auch erst nach und nach klar.


LG

r_r
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Wenn die Länge variabel ist, sollte meine Methode funktionieren. Und [v+-] bedeutet ja, dass eines der Zeichen vorkommen soll, es kann z.B. ruhig immer das - sein.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

mawe hat geschrieben:Wenn die Länge variabel ist, sollte meine Methode funktionieren. Und [v+-] bedeutet ja, dass eines der Zeichen vorkommen soll, es kann z.B. ruhig immer das - sein.
Bin noch nicht bis zu deinem vorgedrungen, :D
Also diese Expressions kann ich echt nur hier bestellen, mir platzt da vorher der Kopf bevor ich das habe:-))

Danke nochmal,

LG

rolgal_reloaded
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Hallo nochmal,

also mawes Ding:-) sollte funktionieren.
Ich wollte das in die Methode suchen meines DataBooks einbauen.
Zwischenzeitlich nur so für die Instanz chords (später überleg ich mir, wie ich die Methode grundsätzlich für versch. Optionen erweitere - ich brauchs jetzt dringend zum Komponieren):

Code: Alles auswählen

def search(self, keyword):
    pattern = re.compile(r"^(?:[v+-]\d)+$")
    return [data for data in self.entries if pattern.match(keyword) in data.itervalues()]

self.entries ist eine Liste mit dicts, die so aussehen:
{"name":"GedanBarai", "kata":"Shodan", "intervalle":"4-6+7"}

Wenn das keyword z. Bsp "4-6+7" lautet müsste es doch klappen,....
Irgendwas übersehe ich, ist mir schon klar, aber was?
Ich bekomme immer eine leere Liste zurück.


LG

rolgal_reloaded
BlackJack

Mit unterschiedlichen Längen:

Code: Alles auswählen

import re


def normalize(string):
    return ''.join(sorted(string[i:i+2] for i in xrange(0, len(string), 2)))


def search(needle, haystack):
    normalized_needle = normalize(needle)
    pattern = r'([v+-]\d){%d}' % (len(needle) // 2)
    for match in re.finditer(pattern, haystack):
        if normalize(match.group(0)) == normalized_needle:
            return True
    return False


def main():
    needle = 'v5-3-7+6'
    haystack = 'spam v5-3+6-7 ham eggs'
    print search(needle, haystack)
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

@BlackJack

Ich habe mich grad ein bisschen mit dem Code beschäftigt.

Code: Alles auswählen

>>> import re
>>> def normalize(string):
	    return ''.join(sorted(string[i:i+2] for i in xrange(0, len(string), 2)))

>>> needle = 'v5-3-7+6'
>>> normalize(needle)
'+6-3-7v5'
>>> 
Was bringts wenn nach der "normalized_needle" gesucht wird?

LG

r_r
Zuletzt geändert von rolgal_reloaded am Montag 11. Juni 2007, 10:40, insgesamt 1-mal geändert.
BlackJack

Na ich hatte das so verstanden, dass die Reihenfolge der "Einzelteile" in der Zeichenkette egal ist. Um also zwei Zeichenketten vergleichen zu können, muss man beide in eine kanonische Form bringen, also durch eine Funktion schicken, die alle möglichen Varianten in einen eindeutigen, "normalisierten" Vertreter der Menge umwandelt.

Die `normalize()`-Funktion sortiert dazu einfach die Einzelteile.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

@BlackJack

So weit so gut. Findest es unbedingt notwendig das "normalisieren" in eine eigene Funktion auszulagern?

LG

rolgal_reloaded
BlackJack

Ja. Einmal ist es kompliziert genug um einen eigenen Docstring zu verdienen, und zum anderen wird es mehrfach benötigt.
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

BlackJack hat geschrieben:Ja. Einmal ist es kompliziert genug um einen eigenen Docstring zu verdienen, und zum anderen wird es mehrfach benötigt.
Integriert in einer Klasse wäre es dann also wieder eine Sache für __methode, um anzuzeigen, dass sie nur für einen internen Aufruf benötigt wird, oder?

LG

rolgal_reloaded
BlackJack

Also ich persönlich stehe nicht so auf den doppelten Unterstrich. In diesem Fall könnte man zum Beispiel argumentieren, das genau die Normalierungsmethode etwas ist, was man in einer Unterklasse vielleicht überschreiben möchte.
jo_hb
User
Beiträge: 72
Registriert: Donnerstag 26. April 2007, 09:21

Moin rolgal,
also mir hat was regexes angeht der 'regex coach' einiges an kopfschmerzen erspart... :)
Da hat man sich fix eingearbeitet und dann kann man sofort sehen welcher Teil einer regex welchen teil eines strings matcht etc... gibts hier

Gruss,
Jo
rolgal_reloaded
User
Beiträge: 312
Registriert: Dienstag 24. Oktober 2006, 19:31

Cool, danke für den Tipp, das muss auf den Rechner :D
Antworten