3

假设字符串:

item1, item1N, item1Z, item1fhg, item1_any_letters, item2, item3, item3N, item3H

我的目标输出很简单

item1, item2, item3

这是目前大约 100,000 行的 Excel 文件,但如果需要临时可以迁移到另一个程序等。

本质上,我需要确定重复项(任何以数字结尾的初始短语),而不考虑数字后面的字母。一些短语可能也有例如“Brand item2, Brand item34”,重复的唯一决定因素是数字之后的任何和所有术语。

关于从哪里开始的任何想法?每个字符串通常包含 2 到 500 个值,以逗号和空格分隔。最终值后面没有逗号。

4

3 回答 3

3
Sub Tester()

    Dim re As Object, match As Object
    Dim dict As Object
    Dim arr, arrItems, x As Long, y As Long
    Dim val, matches, valMatch


    Set dict = CreateObject("scripting.dictionary")
    Set re = CreateObject("VBScript.RegExp")
    re.Pattern = "([\w ]+\d+)"
    re.ignorecase = True
    re.Global = True

    arr = ActiveSheet.Range("A1:A100").Value

    For x = LBound(arr, 1) To UBound(arr, 1)
        arrItems = Split(arr(x, 1), ",")
        dict.RemoveAll
        For y = LBound(arrItems) To UBound(arrItems)

            val = Trim(arrItems(y))

            If re.Test(val) Then
               Set matches = re.Execute(val)
               valMatch = matches(0).Value
               If Not dict.exists(valMatch) Then dict.Add valMatch, 1
            End If
        Next y

        Debug.Print arr(x, 1)
        Debug.Print Join(dict.keys, ",") 'where do you want this?

    Next x

End Sub
于 2012-06-27T00:01:03.600 回答
2

一种 VBA 方法,类似于 Tim 的第一个途径

  1. 使用 aRegExp删除无效字符(数字后和逗号前的字符)
  2. 消除重复
    a) 使用 a Dictionary
    b) Excel 的内置删除重复功能(写入工作表)

    Const strDelim = ", "
    
    Sub TestMe()
    Dim strTest As String
    Dim x
    strTest = "item1, item1N, item1Z, item1fhg, item1_any_letters, item2, item3, item3N, item3H"
    x = Split(DeDupe(strTest), strDelim)
    'fix last element
    x(UBound(x)) = Left$(x(UBound(x)), Len(x(UBound(x))) - 1)
    Call Method2(x)
    End Sub
    
    Sub Method2(ByVal x)
    Dim objDic As Object
    Dim y As Variant
    Set objDic = CreateObject("Scripting.Dictionary")
    Dim lngRow As Long
    For lngRow = LBound(x) To UBound(x)
    objDic(x(lngRow)) = 1
    Next lngRow
    MsgBox Join(objDic.keys, strDelim)
    End Sub      
    
    Function DeDupe(strIn As String) As String
    Dim objRegex As Object
    Set objRegex = CreateObject("vbscript.regexp")
    With objRegex
    .Global = True
    .Pattern = "(.+?\d+)[^\d]+(,|$)"
    DeDupe = .Replace(strIn, "$1,")
    End With
    End Function
    

Option B

    'another potential option. Not applied in this code
    Sub Method1(ByVal x)
    Dim y As Variant
    Dim rng1 As Range
    With ActiveSheet
    .[a1].Resize(UBound(x) + 1, 1) = Application.Transpose(x)
    .Columns("A").RemoveDuplicates Columns:=1, Header:=xlNo
    y = Application.Transpose(Range([a1], Cells(Rows.Count, "A").End(xlUp)))
    End With
    MsgBox Join(y, strDelim)
    End Sub
于 2012-06-27T00:20:19.670 回答
0

这可能是不完美的,因为它是一种快速破解,只删除最右边的非数字字符串。您将需要一些正则表达式知识来调整它以满足您的需求。

不管怎样,按照这里给出的“安装”步骤,保存模块,你就可以在你的工作表中写一个公式,比如

=S(A1;"[^0-9]*$";"")

例如,在 B1 细胞中。如果 A1 单元格包含“Item 1234 blah blah”,那么 B1 现在将包含“Item 1234”。将公式拖到 B 列的所有单元格中,并将值保存到另一个 Excel 文件进行排序(或者您可以尝试就地排序和小计)。

不幸的是,我不认为在 100,000+ 个单元格中这样做是可行的(我什至建议不要就地小计)。

通过为 Windows 安装文本工具(sed、grep、uniq...)并通过过滤器运行文件,您会得到更好的服务。假设每一行代表一个项目如上,一个过滤器如

sed -e 's/^\([^0-9][^0-9]*[0-9][0-9]*\).*/\1/g' | sort | uniq -c | sort -rn

会得到你的 100,000 行文件并返回类似

79283 Item 1
 1234 Item 2
  993 Item 3
  ..........

(在某些平台上,您可以编写 (\D+\d+) 而不是 ([^0-9]...,但我不确定 Windows 的行为)。

更好的工具选择是 (Strawberry)Perl,它也支持 CSV,或者 Python 语言。

于 2012-06-26T22:14:56.790 回答