Google 表格中的模糊匹配

问题描述 投票:0回答:5

尝试将 GoogleSheets 中的两列与 C 列中的此公式进行比较:

=if(A1=B1,"","Mismatch") 

工作正常,但我收到了很多误报:

A. B C
玛丽乔 玛丽·乔
杰伊、蒂姆 蒂姆·杰伊 不匹配
萨姆·罗恩 萨姆·罗恩 不匹配
杰克*马 马云 不匹配

有什么想法如何运作吗?

regex if-statement google-apps-script google-sheets google-sheets-formula
5个回答
6
投票

这使用基于分数的方法来确定匹配。您可以根据该分数确定匹配/不匹配:

Score Formula = getMatchScore(A1,B1)
Match Formula = if(C1<.7,"mismatch",)
function getMatchScore(strA, strB, ignoreCase=true) {
  strA = String(strA);
  strB = String(strB)
  const toLowerCase = ignoreCase ? str => str.toLowerCase() : str => str;
  const splitWords = str => str.split(/\b/);
  let [maxLenStr, minLenStr] = strA.length > strB.length ? [strA, strB] : [strB, strA]; 
  
  maxLenStr = toLowerCase(maxLenStr);
  minLenStr = toLowerCase(minLenStr);

  const maxLength = maxLenStr.length;
  const minLength = minLenStr.length;
  const lenScore = minLength / maxLength;

  const orderScore = Array.from(maxLenStr).reduce(
    (oldItem, nItem, index) => nItem === minLenStr[index] ? oldItem + 1 : oldItem, 0
  ) / maxLength;

  const maxKeyWords = splitWords(maxLenStr);
  const minKeyWords = splitWords(minLenStr);

  const keywordScore = minKeyWords.reduce(({ score, searchWord }, nItem) => {
    const newSearchWord = searchWord?.replace(new RegExp(nItem, ignoreCase ? 'i' : ''), '');
    score += searchWord.length != newSearchWord.length ? 1: 0;

    return { score, searchWord: newSearchWord };
  }, { score: 0, searchWord: maxLenStr }).score / minKeyWords.length;

  const sortedMaxLenStr = Array.from(maxKeyWords.sort().join(''));
  const sortedMinLenStr = Array.from(minKeyWords.sort().join(''));

  const charScore = sortedMaxLenStr.reduce((oldItem, nItem, index) => { 
    const surroundingChars = [sortedMinLenStr[index-1], sortedMinLenStr[index], sortedMinLenStr[index+1]]
    .filter(char => char != undefined);
    
    return surroundingChars.includes(nItem)? oldItem + 1 : oldItem
  }, 0) / maxLength;

  const score = (lenScore * .15) + (orderScore * .25) + (charScore * .25) + (keywordScore * .35);

  return score;
}

3
投票

尝试:

=ARRAYFORMULA(IFERROR(IF(LEN(
 REGEXREPLACE(REGEXREPLACE(LOWER(A1:A), "[^a-z ]", ), 
 LOWER("["&B1:B&"]"), ))>0, "mismatch", )))


3
投票

通过 Google Sheets 公式实现模糊匹配会很困难。如果您想一次填充所有行,我建议您使用此公式或完整的脚本(均通过 Google Apps 脚本)。

自定义公式:

function fuzzyMatch(string1, string2) {
  string1 = string1.toLowerCase()
  string2 = string2.toLowerCase();
  var n = -1;

  for(i = 0; char = string2[i]; i++)
    if (!~(n = string1.indexOf(char, n + 1))) 
      return 'Mismatch';
};

它的作用是比较第二个字符串的字符顺序是否与第一个字符串的顺序相同。有关返回不匹配的情况,请参阅下面的示例数据。

输出:

注:

  • 最后一行不匹配,因为第二个字符串中有
    r
    ,但在第一个字符串中找不到,因此未满足正确的顺序。
  • 如果这不符合您的测试用例,请添加一个更明确的列表,该列表将显示公式/函数的预期输出,以便可以对其进行调整,或者查看player0的答案,该答案仅使用Google表格公式并且对条件不太严格.

参考:


0
投票

传统模糊匹配的主要局限性是它没有考虑字符串之外的相似性。主题聚类需要语义理解。 Goodlookup 是电子表格用户的一项智能功能,非常接近语义理解。它是一个预训练的模型,具有 GPT-3 的直观性和模糊匹配的连接功能。像 vlookup 或索引匹配一样使用它来加速 Google Sheets 中的主题聚类工作。

https://www.goodlookup.com/


0
投票

如果您有兴趣简单地比较两列,那么您可以使用FUZZYMATCH。这是我创建的名为 Flookup Data Wrangler 的工具中的一个功能,并且完全免费,无需注册即可使用。

此函数将获取任意两个文本条目并返回相似度分数,其范围从 0(表示不相似)到 1(表示完全匹配)。这使您可以灵活地确定什么构成匹配、什么不构成匹配。它可以比较任何形式的字符串,甚至可以考虑交换的子字符串。

这是基本语法:

FUZZYMATCH(left_string, right_string)

参数含义如下:

  • left_string: 要与“right_string”进行比较的主要文本条目。 它可以是单个细胞,例如
    A1
    或一系列单元格,例如
    A1:A500
  • right_string: 要比较的辅助文本条目 “左字符串”。它可以是一系列单元格,例如
    B1:B500

对于您的特定情况,您可以在单元格

C1
中输入此公式以对数据进行逐行比较:

FUZZYMATCH(A1:A6, B1:B6)

除此之外,FUZZYMATCH也可以通过菜单功能执行。这样做的好处是,在其他条件不变的情况下,它可以处理超过 10 倍的数据。该版本还具有用于比较较大文本正文的额外功能。

如果您有兴趣了解更多有关FUZZYMATCH菜单功能的信息,请点击这里

© www.soinside.com 2019 - 2024. All rights reserved.