【问题标题】:How can I split an array in VBA with a delimiter based on a regex condition?如何使用基于正则表达式条件的分隔符在 VBA 中拆分数组?
【发布时间】:2019-10-17 14:34:25
【问题描述】:

我有这样的输入:

apple, orange, (pear, banana, grape), mango 

我想拆分为:

apple
orange
(pear, banana, grape)
mango

我不完全理解正则表达式,但我想我会使用我在这里找到的 ,(?![^()]*)) - Java split string on comma(,) except when between parenthesis ()

我使用的是 VBA,所以如果我将输入存储在一个数组中,我通常会这样做:

array = Split(string, ",")

但这会产生如下结果:

apple
orange
(pear
banana
grape)
mango

我不想要的。

我很确定我可以找到一种方法来替换 ( 和 ),使它们从输出中消失,但我不知道如何将我的正则表达式字符串逻辑提供给我的 VBA 公式。

我认为这样的事情会起作用:

array = Split(string, ",(?![^()]*\))")

但事实并非如此。我确实启用了“Microsoft VBScript Regular Expressions 5.5”参考,但它似乎没有帮助。

感谢任何建议。

谢谢,

【问题讨论】:

标签: regex excel vba


【解决方案1】:

正则表达式的替代品:

Sub mytry()
    Dim str As String
    str = "apple, orange, (pear, banana, grape), mango "

    Dim perenSplt() As String
    perenSplt = Split(Replace(str, ")", ")("), "(")

    str = ""

    Dim i As Long
    For i = LBound(perenSplt) To UBound(perenSplt)
        If InStr(perenSplt(i), ")") Then
            perenSplt(i) = "(" & Replace(perenSplt(i), ",", "|")
        End If
        str = str & perenSplt(i)
    Next i

    Dim finalSplt() As String
    finalSplt = Split(str, ",")

    For i = LBound(finalSplt) To UBound(finalSplt)
        If InStr(str, "(") > 0 Then
            finalSplt(i) = Trim(Replace(finalSplt(i), "|", ","))
        Else
            finalSplt(i) = Trim(finalSplt(i))
        End If
    Next i

    ActiveSheet.Range("A1").Resize(,UBound(finalSplt) + 1) = finalSplt

End Sub

【讨论】:

  • 您能解释一下这是如何工作的吗?我不喜欢在没有更好理解的情况下复制/粘贴代码。看起来您尝试将 ) 更改为 )( 然后将字符串拆分为 ( 所以它最终为:“apple, orange, ", "pear,banana,grape)" 和 ", mango" 然后你检查 ) 是否存在在结果中,如果是这样,将逗号替换为 |然后你稍后替换 |再次昏迷……?
  • 是的,这正是它的工作原理。将, 替换为| 后,我在, 上进行了拆分,并且由于当时不存在,,因此它不会拆分() 内的单词。然后作为最后一步,我从输出中删除所有无关的空格。
  • 在无法共享电子表格的情况下,我能够将您的逻辑合并到我的代码中并使其大部分工作。我正在循环给定范围内的每一行。对于每一行,我尝试访问该行唯一的 finalSplt(0)、finalSplt(1) 和 finalSplt(2) 以访问数组中的第一个、第二个和第三个元素。
  • finalSplt(0) 似乎始终如一地工作,但是当我尝试访问 finalSplt(1) 或 finalSplt(2) 并将其添加到新单元格的值时,只有一些元素被写入.例如如果 finalSplt(0) = apple, finalSplt(1) = (pear,banana,orange,grape), and finalSplt(2) = mango,我有时只能得到前两个结果。最终我得到一个下标超出范围的错误。使用会导致这种情况的方法是否有任何限制,或者我的代码可能有其他问题?
  • 这意味着拆分数组中的“单词”更少。如果字符串只有Apple, (Pear, Orange, Banana),则只有finalSplt(0)finalSplt(1)finalSplt(2) 会出错,因为该行没有这样的项目。
【解决方案2】:

RegEx 的另一种可能性:

Function GetArray(ByVal str As String) As Variant       
    Dim s As String, v As Variant
    For Each v In Split(Replace(str & " ", ")", "("), "(")
        s = s & IIf(Right(v, 1) <> " ", "(" & v & ")", Replace(v, ",", "|"))
    Next

    GetArray = Split(Replace(WorksheetFunction.Trim(s), "| ", "|"), "|")
End Function

您可以在主代码中使用,例如:

    Dim myArray As Variant        
    myArray = GetArray("apple, orange, (pear, banana, grape), mango")
    Range("A1").Resize(ubound(myArray) + 1).Value = Application.Transpose(myArray)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 2019-04-26
    • 1970-01-01
    相关资源
    最近更新 更多