Überprüfen Sie, ob eine Zeichenfolge eine mögliche Abkürzung für einen Namen ist
-
27-10-2019 - |
Frage
Ich versuche, einen Python-Algorithmus zu entwickeln, um zu überprüfen, ob eine Zeichenfolge eine Abkürzung für ein anderes Wort sein könnte. Zum Beispiel
-
fck
ist eine Übereinstimmung mitfc kopenhavn
, da es mit den ersten Zeichen des Wortes übereinstimmt.fhk
würde nicht übereinstimmen. -
fco
sollte nicht mitfc kopenhavn
übereinstimmen, da niemand irl FC Kopenhavn als FCO abkürzen würde. -
irl
ist eine Übereinstimmung mitin real life
. -
ifk
ist eine Übereinstimmung mitifk goteborg
. -
aik
ist eine Übereinstimmung mitallmanna idrottskluben
. -
aid
ist eine Übereinstimmung mitallmanna idrottsklubben
. Dies ist keine echte Abkürzung für Teamnamen, aber ich denke, es ist schwierig, sie auszuschließen, es sei denn, Sie wenden domänenspezifisches Wissen darüber an, wie schwedische Abkürzungen gebildet werden. -
manu
ist eine Übereinstimmung mitmanchester united
.Es ist schwer, die genauen Regeln des Algorithmus zu beschreiben, aber ich hoffe, meine Beispiele zeigen, wonach ich suche.
Update Ich habe einen Fehler beim Anzeigen der Zeichenfolgen mit den übereinstimmenden Großbuchstaben gemacht. Im realen Szenario sind alle Buchstaben in Kleinbuchstaben geschrieben, sodass es nicht so einfach ist, nur zu überprüfen, welche Buchstaben in Großbuchstaben geschrieben sind.
Lösung
Damit sind alle Tests bestanden, einschließlich einiger zusätzlicher Tests, die ich erstellt habe.Es verwendet Rekursion.Hier sind die Regeln, die ich verwendet habe:
- Der erste Buchstabe der Abkürzung muss mit dem ersten Buchstaben von übereinstimmen der Text
-
Der Rest der Abkürzung (die Abkürzung abzüglich des ersten Buchstabens) muss eine Abkürzung für sein:
- die restlichen Wörter oder
- der verbleibende Text ab
jede Position im ersten Wort.
tests=( ('fck','fc kopenhavn',True), ('fco','fc kopenhavn',False), ('irl','in real life',True), ('irnl','in real life',False), ('ifk','ifk gotebork',True), ('ifko','ifk gotebork',False), ('aik','allmanna idrottskluben',True), ('aid','allmanna idrottskluben',True), ('manu','manchester united',True), ('fz','faz zoo',True), ('fzz','faz zoo',True), ('fzzz','faz zoo',False), ) def is_abbrev(abbrev, text): abbrev=abbrev.lower() text=text.lower() words=text.split() if not abbrev: return True if abbrev and not text: return False if abbrev[0]!=text[0]: return False else: return (is_abbrev(abbrev[1:],' '.join(words[1:])) or any(is_abbrev(abbrev[1:],text[i+1:]) for i in range(len(words[0])))) for abbrev,text,answer in tests: result=is_abbrev(abbrev,text) print(abbrev,text,result,answer) assert result==answer
Andere Tipps
Hier ist eine Möglichkeit, das zu erreichen, was Sie anscheinend tun möchten
import re
def is_abbrev(abbrev, text):
pattern = ".*".join(abbrev.lower())
return re.match("^" + pattern, text.lower()) is not None
Das Caret stellt sicher, dass das erste Zeichen der Abkürzung mit dem ersten Zeichen des Wortes übereinstimmt. Dies sollte für die meisten Abkürzungen zutreffen.
Bearbeiten :
Ihr neues Update hat die Regeln ein wenig geändert.Wenn Sie "(|.*\s)"
anstelle von ".*"
verwenden, stimmen die Zeichen in der Abkürzung nur überein, wenn sie nebeneinander liegen oder wenn das nächste Zeichen am Anfang eines neuen Wortes erscheint.
Dadurch wird der fck
korrekt mit dem FC Kopenhavn
abgeglichen, der fco
jedoch nicht.
Das Abgleichen von aik
mit allmanna idrottskluben
funktioniert jedoch nicht , da dies Kenntnisse der schwedischen Sprache erfordert und nicht so trivial ist.
Hier ist der neue Code mit der geringfügigen Änderung
import re
def is_abbrev(abbrev, text):
pattern = "(|.*\s)".join(abbrev.lower())
return re.match("^" + pattern, text.lower()) is not None
@Ocaso Protal
sagte im Kommentar how should you decide that aik is valid, but aid is not valid?
und er hat Recht.
Das Algo, das mir in den Sinn kam, ist die Arbeit mit word threshold
(Anzahl der durch Leerzeichen getrennten Wörter).
words = string.strip().split()
if len(words) > 2:
#take first letter of every word
elif len(words) == 2:
#take two letters from first word and one letter from other
else:
#we have single word, take first three letter or as you like
Sie müssen Ihre Logik definieren, Sie können die Abkürzung nicht blind finden.
Ihr Algorithmus scheint einfach zu sein - die Abkürzung ist die Verkettung aller Großbuchstaben. also:
upper_case_letters = "QWERTYUIOPASDFGHJKLZXCVBNM"
abbrevation = ""
for letter in word_i_want_to_check:
if letter in letters:
abbrevation += letter
for abb in _list_of_abbrevations:
if abb=abbrevation:
great_success()
Das könnte gut genug sein.
def is_abbrevation(abbrevation, word):
lowword = word.lower()
lowabbr = abbrevation.lower()
for c in lowabbr:
if c not in lowword:
return False
return True
print is_abbrevation('fck', 'FC Kopenhavn')