【问题标题】:python how to dynamically find a persons name in a stringpython如何在字符串中动态查找人名
【发布时间】:2019-03-11 13:55:03
【问题描述】:

我正在做一个项目,我必须使用语音到文本作为输入来确定呼叫谁,但是使用语音到文本会产生一些意想不到的结果,所以我想要对字符串进行一点动态匹配,我我从小开始尝试匹配 1 个单一的名字,我的名字是 Nick Vaes,我尝试将我的名字与口语文本匹配,但我也希望它匹配例如某些文本是 Nik 或其他东西,理想情况下我如果只有 1 个字母是错误的,那么希望有一些可以匹配所有内容的东西,所以

尼克 ick 尼克 网卡 恩克

都符合我的名字,我目前的简单代码是:

  def user_to_call(s):
  if "NICK" or "NIK" in s.upper(): redirect = "Nick"
  if redirect: return redirect

对于 4 个字母的名称,可以将所有可能性都放在过滤器中,但对于 12 个字母的名称,这有点矫枉过正,因为我很确定它可以更有效地完成。

【问题讨论】:

  • 我给你看一下你的表情进化步骤:"NICK" or "NIK" in s.upper()("NICK") or ("NIK" in s.upper())True or <I don't care since it is going to be True anyway>True
  • 也许可以尝试使用difflib 并在遇到问题时提出单独的问题。

标签: python regex


【解决方案1】:

你需要使用Levenshtein_distance

一个python实现是nltk

import nltk
nltk.edit_distance("humpty", "dumpty")

【讨论】:

  • 这个模糊字符串确实是我正在寻找的,但是我如何在我的情况下使用它?我了解这将如何在字符串 1 on 1 上工作,但我尝试匹配字符串的一部分。我想匹配我的名字,但是当有人说“我想联系尼克”时,它应该仍然匹配。
  • 将句子拆分成单词:['i','would','like',...]
  • 我学到了一些新东西,+1:我不知道 Levenshtein 距离。
【解决方案2】:

你基本上需要的是模糊字符串匹配,见:

https://en.wikipedia.org/wiki/Approximate_string_matching

https://www.datacamp.com/community/tutorials/fuzzy-string-python

基于此,您可以检查输入与您的字典相比有多相似:

 from fuzzywuzzy import fuzz

 name = "nick"
 tomatch = ["Nick", "ick", "nik", "nic", "nck", "nickey", "njick", "nickk", "nickn"]
 for str in tomatch:
    ratio = fuzz.ratio(str.lower(), name.lower())
    print(ratio)

此代码将产生以下输出:

100
86
86
86
86
80
89
89
89

您必须尝试不同的比率并检查哪个符合您的要求,以免错过一个字母

【讨论】:

    【解决方案3】:

    据我了解,您没有看到任何模糊匹配。 (因为您没有支持其他回复)。 如果您只是想评估您在请求中指定的内容,这里是代码。我在打印相应消息的地方添加了一些附加条件。随意删除它们。

    def wordmatch(baseword, wordtoMatch, lengthOfMatch):
        lis_of_baseword = list(baseword.lower())
        lis_of_wordtoMatch = list(wordtoMatch.lower()) 
        sum = 0
        for index_i, i in enumerate(lis_of_wordtoMatch):
            for index_j, j in enumerate(lis_of_baseword):
                if i in lis_of_baseword:
                    if i == j and index_i <= index_j:
                        sum = sum + 1
                        break
                    else:
                        pass
                else:
                    print("word to match has characters which are not in baseword")
                    return 0
        if sum >= lengthOfMatch and len(wordtoMatch) <= len(baseword):
            return 1
        elif sum >= lengthOfMatch and len(wordtoMatch) > len(baseword):
            print("word to match has no of characters more than that of baseword")
            return 0
        else:
            return 0
    
    base = "Nick"
    tomatch = ["Nick", "ick", "nik", "nic", "nck", "nickey","njick","nickk","nickn"]
    wordlength_match = 3 # this says how many words to match in the base word. In your case, its 3
    
    for t_word in tomatch:
        print(wordmatch(base,t_word,wordlength_match))
    

    输出如下所示

    1
    1
    1
    1
    1
    word to match has characters which are not in baseword
    0
    word to match has characters which are not in baseword
    0
    word to match has no of characters more than that of baseword
    0
    word to match has no of characters more than that of baseword
    0
    

    让我知道这是否符合您的目的。

    【讨论】:

    • 感谢您的回答!但是目前我正在使用模糊匹配,因为我认为它对于我的项目的其余部分更具可扩展性。
    猜你喜欢
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 2013-08-06
    相关资源
    最近更新 更多