如何从仅包含数字s的Excel文本字符串中删除最后一组括号

如何从仅包含数字s的Excel文本字符串中删除最后一组括号,excel,vba,parentheses,Excel,Vba,Parentheses,我有一个excel电子表格,有超过50000个条目。这些条目有一个名称和地址,有时还有一个电话号码,都在同一个字符串中。我将重点放在字符串的电话号码部分,该部分始终位于末尾并用括号括起来。我一直在尝试使用VBA代码来解决这个问题。 如何从只包含括号之间的数字s的Excel文本字符串中删除最后一组括号。在任何给定的字符串中,可能没有括号,也可能有多个括号,但我只想删除最后一组括号,并将其中包含的数字保留在字符串中 示例字符串“Toone Carkeet J.,agt.,Alliance Assur

我有一个excel电子表格,有超过50000个条目。这些条目有一个名称和地址,有时还有一个电话号码,都在同一个字符串中。我将重点放在字符串的电话号码部分,该部分始终位于末尾并用括号括起来。我一直在尝试使用VBA代码来解决这个问题。 如何从只包含括号之间的数字s的Excel文本字符串中删除最后一组括号。在任何给定的字符串中,可能没有括号,也可能有多个括号,但我只想删除最后一组括号,并将其中包含的数字保留在字符串中

示例字符串“Toone Carkeet J.,agt.,Alliance Assurance Co.Ltd.(Provident Life branch),3 St.Andrew St.(1936)”我曾尝试使用
VBScript.RegExp
来定义“(1936)”,但我无法使
RegExp
匹配字符串并将括号()替换为“”

范围内每个单元格的

如果strPattern“”则
条纹=细胞
用正则表达式
.Pattern=“\([0-9])*)”
.Global=False
以
如果.Pattern=True,则
替换(Cell.Value,(,)
如果结束

这里有两个不依赖正则表达式的快速用户定义函数。第一个使用VBA的StrReverse,第二个使用InStrRev

Function RemoveParens1(str As String)

    str = StrReverse(str)

    str = Replace(str, "(", vbNullString, 1, 1)
    str = Replace(str, ")", vbNullString, 1, 1)

    RemoveParens1 = StrReverse(str)

End Function

Function RemoveParens2(str As String)

    Dim o As Integer, c As Integer

    o = InStrRev(str, "(")
    c = InStrRev(str, ")")

    str = Left(str, c - 1) & Mid(str, c + 1)
    str = Left(str, o - 1) & Mid(str, o + 1)

    RemoveParens2 = str

End Function
如果您不想使用UDF,只需选择您喜欢的逻辑方法,并根据自己的目的进行调整

这里还有一个使用正则表达式的Replace

Function RemoveParens3(str As String)

    Static rgx As Object, cmat As Object, tmp As String

    If rgx Is Nothing Then Set rgx = CreateObject("vbscript.regexp")

    With rgx
        .Global = True
        .MultiLine = True
        .IgnoreCase = False
        .Pattern = "\([0-9]*\)"

        If .test(str) Then
            Set cmat = .Execute(str)
            tmp = cmat.Item(cmat.Count - 1)
            tmp = Mid(tmp, 2, Len(tmp) - 2)
            str = .Replace(str, tmp)
        End If
    End With

    RemoveParens3 = str

End Function

下面是一个使用与您类似的逻辑的示例。 我更改了范围变量的名称,因为为命名变量使用关键字不是一个好主意,即使编辑器允许这样做

我们不只是删除括号,而是将整个
(nnnn)
子字符串与捕获组中的数字进行匹配,然后仅用捕获组替换该匹配

因为如果没有匹配项,Replace不会做任何事情,所以不需要测试

另外,请注意,我们在循环外部设置了正则表达式

With regEx
    .Pattern = "\((\d+)\)"
    .Global = False
End With

For Each myCell In myRange
    myCell = regEx.Replace(myCell, "$1")
Next myCell
如果由于具有相同模式的其他子字符串而有必要,可以更改模式,以确保匹配位于行的末尾,或者它是字符串中该类型的最后一个模式

例如:

  • 行末尾的子字符串

  • 子串最后一个

如果您的字符串位于单元格中的多行中,则可能需要进行其他修改。

Dim x,y,z尽可能长
Dim x, y, z As Long
x = 2 'ASSUMING YOUR DATA START AT RANGE A2
With Sheet1
Do While .Cells(x, 1).Value <> ""
    If Right(.Cells(x, 1).Value, 1) = ")" Then
        .Cells(x, 1).Value = Replace(.Cells(x, 1).Value, ")", "")
        z = VBA.Len(.Cells(x, 1).Value)
        For y = z To 1 Step -1
            If Mid(.Cells(x, 1).Value, y, 1) = "(" Then
                .Cells(x, 1).Value = Replace(.Cells(x, 1).Value, "(", "")
                Exit For
            End If
        Next y

        x = x + 1
    End If
Loop
End With
x=2'假设数据从A2范围开始 附页1 执行While.Cells(x,1).Value“” 如果正确(.Cells(x,1).Value,1)=“”,则 .Cells(x,1).Value=Replace(.Cells(x,1).Value,”),“”) z=VBA.Len(.Cells(x,1).Value) 对于y=z到1步骤-1 如果Mid(.Cells(x,1).Value,y,1)=”(“那么 .Cells(x,1).Value=Replace(.Cells(x,1).Value,(“,”) 退出 如果结束 下一个y x=x+1 如果结束 环 以
1.User11450033非常感谢您的快速结果。在3个函数中,第三个是最好的,因为它提取到单元格“Bxxx”只是括号内的数字。我感谢您代表我所做的工作。但是,我更喜欢在模块中使用VBA Sub,以便更新原始字符串。我是这个网站的新手,所以我发现我的脚可以这么说。至于VBA,我是一个完全的新手,但热衷于学习和适应。再次感谢您非常有用的输入SUSER11450033 J一个简单的问题:我在单元格“Bxx”中输入了公式,并在括号中添加了单元格编号以引用正确的单元格。这是使用该函数的正确方法吗?我对VBA不熟悉,也不熟悉这个网站,所以可能有点笨!要在sub中使用它,可以非常简单,只要
range(“A1”)=RemoveParens3(range(“A1”).Text)
.Pu在一个循环中,你可以处理一列类似的字符串值。要使用你的算法,你可以使用
.Test
方法。但是
Replace
如果不匹配,就不会
Replace
,因此测试是多余的。Joel感谢你的输入,这非常感谢Ron Rosenfeld,你的代码很好。问题:在循环外部设置正则表达式会导致什么样的安全防护?提高性能?标准做法?-我是VBA新手,因此更好地了解良好做法。非常感谢您的帮助,非常感谢appreciated@DJP2019如果您在循环中创建regex对象,那么您将每年创建一个新对象通过循环告诉我——50000个正则表达式对象可能会引起问题。只创建一个对象并每次重用似乎更有效。
\((\d+)\)$
\((\d+)\)(?!.*\(\d+\))
Dim x, y, z As Long
x = 2 'ASSUMING YOUR DATA START AT RANGE A2
With Sheet1
Do While .Cells(x, 1).Value <> ""
    If Right(.Cells(x, 1).Value, 1) = ")" Then
        .Cells(x, 1).Value = Replace(.Cells(x, 1).Value, ")", "")
        z = VBA.Len(.Cells(x, 1).Value)
        For y = z To 1 Step -1
            If Mid(.Cells(x, 1).Value, y, 1) = "(" Then
                .Cells(x, 1).Value = Replace(.Cells(x, 1).Value, "(", "")
                Exit For
            End If
        Next y

        x = x + 1
    End If
Loop
End With