使用 VBA 解析和拆分带有通配符的字符串?

Posted

技术标签:

【中文标题】使用 VBA 解析和拆分带有通配符的字符串?【英文标题】:Using VBA to parse and split a string with wildcards? 【发布时间】:2016-05-06 14:13:27 【问题描述】:

我有一张表,其中包含字母数字字符的项目编号,以及行中的一堆其他信息。有时,相似的项目组合成一行,项目编号的差异会显示为 (X/Y) 以选择在项目编号中的该点使用哪个字符(不仅仅是 X 或 Y,可以是任何字母数字特点)。换句话说,这些条目将如下所示:

AB(X/Y)CD123

我需要一种方法将其分成两个项目编号 ABXCD123 和 ABYCD123。之后,我必须在当前行下方创建一行并将当前行复制到其中,并更改项目编号,但这部分很容易。我尝试使用 InStr 来标记 (X/Y),但我不知道如何提取 X 和 Y 字符以使用它们创建新字符串。我也不知道通配符是否适用于 InStr,而且我对 RegEx 不太熟悉。

有什么想法吗?

【问题讨论】:

不清楚你的数据范围(多少行/列),也不清楚你想把结果放在哪里。 就像我说的,这部分很简单。这是一张要解析的大表格。一旦找到这些问题项目编号之一,它应该将当前行复制到数组或其他东西中,并将其插入到当前行下方。对我来说困难的部分是如何更改项目编号,以便 (A/B) 部分在一行变为 A,在另一行变为 B。一旦我有了一些字符串变量或带有那些修改过的项目编号的东西,剩下的就很好了。 【参考方案1】:

这里是对 UDF² 中正则表达式¹ 的简要介绍。

Function partNums(str As String, _
                  Optional num As Integer = 1)
    Dim tmp As String
    Static rgx As Object

    'with rgx as static, it only has to be created once; beneficial when filling a long column with this UDF
    If rgx Is Nothing Then
        Set rgx = CreateObject("VBScript.RegExp")
    End If
    partNums = vbNullString

    With rgx
        .Global = True
        .IgnoreCase = True
        .MultiLine = False
        .Pattern = "\([A-Z]1/[A-Z]1\)"
        If .Test(str) Then
            tmp = .Execute(str)(0)
            Select Case num
                Case 2
                    tmp = Mid(tmp, 4, 1)
                Case Else
                    tmp = Mid(tmp, 2, 1)
            End Select
            partNums = .Replace(str, tmp)
        End If
    End With
End Function

在 B2:B3 中,

=partNums(A2)
=partNums(A3,2)

            

这是一个大量重复的 UDF,可处理 1 到 3 个字符。

Function partNums(str As String, _
                  Optional num As Integer = 1)
    Dim tmp As String
    Static rgx As Object

    'with rgx as static, it only has to be created once; beneficial when filling a long column with this UDF
    If rgx Is Nothing Then
        Set rgx = CreateObject("VBScript.RegExp")
    End If
    partNums = vbNullString

    With rgx
        .Global = True
        .IgnoreCase = True
        .MultiLine = False
        .Pattern = "\([A-Z]1,3/[A-Z]1,3\)"
        If .Test(str) Then
            tmp = .Execute(str)(0)
            tmp = Split(Replace(Replace(tmp, Chr(40), vbNullString), Chr(41), vbNullString), Chr(47))(num - 1)
            partNums = .Replace(str, tmp)
        End If
    End With
End Function

            


¹ regex 的问题通常可以通过How to use Regular Expressions (Regex) in Microsoft Excel both in-cell and loops 中的解决方案来回答。

² 用户定义函数(又名 UDF)被放入标准模块代码表中。点击Alt+F11,当VBE打开时,立即使用下拉菜单Insert ► ModuleAlt+I,M)。将功能代码粘贴到标题为 Book1 - Module1 (Code) 的新模块代码表中。点击 Alt+Q 返回您的工作表。

【讨论】:

超级酷。这对我来说也是全新的信息,但完全胜过我的方法 看起来这会很好用。感谢您的协助。除了您发布的链接之外,还有其他学习 RegEx 的好资源吗? 如果它没有被覆盖there 那么它可能不存在。我会告诉你,'给我一个正则表达式模式' 风格的查询通常不被视为 SO 问题,而没有一些原始努力的证据。 我并不是专门寻找 RegEx 解决方案,只是说我对此一无所知,所以我还没有尝试过。我正在使用两个拆分进行辩论,一个在 ( 和一个在 / 然后使用左或其他东西,直到你发布你的答案。这更优雅,我很感激。 @DougCoats - 欢迎来到 [regex] rabbithole Alice。在迟到之前喝杯茶。

以上是关于使用 VBA 解析和拆分带有通配符的字符串?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Excel VBA 检查字符串是不是在数组中或不包括通配符

Excel 列表对象中的 VBA 通配符

vba 拆分功能的类型错误和不匹配

vba 按顺序打开文件夹下含特定字符的工作簿

Excel vba拆分功能不起作用

如何在 Python 中拆分和解析字符串?