我正在尝试开发一个python算法来检查字符串是否可以是另一个单词的缩写。例如
fck
是fc kopenhavn
的匹配项,因为它匹配单词的前几个字符。 fhk
不匹配。fco
不应与fc kopenhavn
匹配,因为没有人会将FC Kopenhavn缩写为FCO。irl
与in real life
匹配。ifk
与ifk goteborg
匹配。aik
与allmanna idrottskluben
匹配。aid
与allmanna idrottsklubben
匹配。这不是一个真正的团队名称缩写,但我想除非您应用有关如何形成瑞典语缩写的领域特定知识,否则很难将其排除。manu
与manchester united
匹配。很难描述算法的确切规则,但我希望我的例子展示我所追求的目标。
更新我在显示匹配字母大写的字符串时犯了一个错误。在实际场景中,所有字母都是小写的,所以它不像检查哪些字母是大写字母那么容易。
答案 0 :(得分:11)
这会通过所有测试,包括我创建的一些额外测试。它使用递归。以下是我使用的规则:
缩写的其余部分(缩写减去第一个字母)必须是以下缩写:
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
答案 1 :(得分:4)
这是一种完成你似乎想要做的事的方法
import re
def is_abbrev(abbrev, text):
pattern = ".*".join(abbrev.lower())
return re.match("^" + pattern, text.lower()) is not None
插入符号确保缩写的第一个字符与单词的第一个字符匹配,对于大多数缩写词应该是正确的。
修改强>:
您的新更新稍微改变了规则。使用"(|.*\s)"
代替".*"
时,缩写中的字符只有在彼此相邻时才会匹配,或者下一个字符出现在新单词的开头。
这会将fck
与FC Kopenhavn
正确匹配,但fco
则不会。
但是,将aik
与allmanna idrottskluben
匹配将不工作,因为这需要了解瑞典语并且不是那么简单。
这是带有次要修改的新代码
import re
def is_abbrev(abbrev, text):
pattern = "(|.*\s)".join(abbrev.lower())
return re.match("^" + pattern, text.lower()) is not None
答案 2 :(得分:4)
@Ocaso Protal
在评论how should you decide that aik is valid, but aid is not valid?
中说,他是对的。
我想到的算法是使用word threshold
(用空格分隔的单词数)。
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
你必须定义你的逻辑,你不能盲目找到缩写。
答案 3 :(得分:0)
您的算法看似简单 - 缩写是所有大写字母的连接。 这样:
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()
答案 4 :(得分:0)
这可能已经足够了。
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')