2016-08-05 59 views
0

我有U和V的地址。我想看看他们是否有点类似,如果他们说“更新”如果不是说“省略”。比较两个地址列

例如U中的246 N High street和V中的246 North High St将返回值Update。 U中的 246 N High Street和V中的458 Auburn Drive将返回值Omit

任何想法?

+1

这是一般的难题。你需要使用某种模糊匹配。查看答案[这里](http://stackoverflow.com/questions/14821345/excel-approximate-text-match)了解如何去做。 –

回答

0

有很多做模糊匹配的算法。在Excel中实现的一个更容易的是N-Gram。

要执行n-gram匹配,我们必须将每个地址分成一组较小字符长度的列表。您的地址246 N High street的2克列表看起来像24,46,6 , N,N , H,Hi,ig,gh,h , s,st,tr,re,ee,et。我们可以用一个3-gram来做同样的事情:246,46 ,6 N, N ,N H, Hi,Hig,igh,gh ,h s, st,str,tre,ree,eet

我们用这两个地址做这个,然后我们可以检查第一个地址列表中的每个项目,看它是否出现在第二个地址列表中;对匹配进行计数并将其除以第一个列表中的项目数。这会给你一个接近他们的百分比。

你可能会喜欢用单元格公式mid()countif()来做到这一点与表单公式,但我认为它只是写在VBA中,并使其成为一个UDF更容易。

Function NGramCompare(string1 As String, string2 As String, intGram As Integer) As Double 
    'Take in two strings and the N-gram 
    Dim intChar As Integer, intGramMatch As Integer 
    Dim ngramList1 As String, ngramList2 As String, nGram As Variant 
    Dim nGramArr1 As Variant 

    'split the first string into a list of ngrams   
    For intChar = 1 To Len(string1) - (intGram-1) 
     If ngramList1 <> "" Then ngramList1 = ngramList1 & "," 
     ngramList1 = ngramList1 & Mid(string1, intChar, intGram) 
    Next intChar 

    'split the secong string into a list of ngrams   
    For intChar = 1 To Len(string2) - (intGram-1) 
     If ngramList2 <> "" Then ngramList2 = ngramList2 & "," 
     ngramList2 = ngramList2 & Mid(string2, intChar, intGram) 
    Next intChar 

    'Split the ngramlist1 into an array through which we can iterate 
    nGramArr1 = Split(ngramList1, ",") 

    'Iterate through array and compare values to ngramlist2 
    For Each nGram In nGramArr1 
     If InStr(1, ngramList2, nGram) Then 
      'we found a match, add to the counter 
      intGramMatch = intGramMatch + 1 
     End If 
    Next nGram 

    'output the percentage of grams matching. 
    NGramCompare = intGramMatch/(UBound(nGramArr1) + 1) 
End Function 

如果你从来没有使用UDF:

  1. 转到Visual Basic编辑器(VBE)使用Alt + F11
  2. 在VBA项目窗口,找到你的工作簿,然后右键点击名称
  3. 选择:插入>>模块
  4. 双击新的模块列表,弹出它的代码窗口
  5. 在这个函数和粘贴保存工作簿

然后,假设地址1是A1和地址2为B1,你可以说,在C1

=NGramCompare(A1, B1, 2) 

其中,对于你的第一个地址,会吐出56%。这似乎是一个相当不错的比赛。如果你发现你获得了太多积极的命中,你可以通过改变最后一个参数来改变你的2克为3克。

把它更进了一步,因此会说“更新”或“忽略”你可以这样做:

=If(NGramCompare(A1, B1, 2)>.30, "Update", "Omit") 

我只是设置,以便它会考虑匹配任何东西30%以上,但你可根据需要进行调整。不管你在哪里设置它,你最终可能会得到一些比较结果是误报或误报,但这就是模糊匹配的方式。

+0

这太棒了,谢谢! – Ryan

+0

哇,这太神奇了,我只是把它和它的工作,很快!非常感谢!! – Ryan

+0

当然可以。过去我曾经遇到过几次这个问题,但直到最近才知道要解决这个问题。我很惊讶网络上没有类似的功能,但我从来没有碰到过。 – JNevill

0

一些幼稚的方法可以是前几个字符

=LEFT(A1,5)=LEFT(B1,5) 

比较或直到它们匹配

=(SUBSTITUTE(SUBSTITUTE(LOWER(A2)," street"," ST")," north "," N ") 
=SUBSTITUTE(SUBSTITUTE(LOWER(B2)," street"," ST")," north "," N ")) 

都可能会变成一个大的难看的公式调整后,更换零件大多数情况下

+0

That = Left会很好的工作,我可以看看前几位数字,看看它们是否匹配。非常感谢 – Ryan

+0

然后在第一个空格之前得到所有东西'= LEFT(A1,FIND(“,A1) - 1)' – Slai