【问题标题】:Excel VBA - String replacement - reg exp?Excel VBA - 字符串替换 - 正则表达式?
【发布时间】:2019-01-08 19:17:16
【问题描述】:

我正在 Excel VBA 中进行一些单词替换。替换单词本身,由任何特殊字符(a-z、A-Z、0-9 除外)分隔,并保留大小写。

正确替换示例(将example 替换为replaced):

One example string > One replaced string

One Example string > One Replaced string

One Example, string > One Replaced, string

One >example< string > One >replaced< string(前后特殊字符)

One dexamples string > One dexamples stringexample 未替换)

我已经通过使用几行使其工作,如下所示。任何想法如何使用正则表达式或类似方法做到这一点?

cel.Replace what:=" " & Rng.Value & " ", replacement:=" " & Rng.Offset(0, 1).Value & " ", MatchCase:=True
cel.Replace what:=" " & Rng.Value & ",", replacement:=" " & Rng.Offset(0, 1).Value & ",", MatchCase:=True
cel.Replace what:=">" & Rng.Value & "<", replacement:=">" & Rng.Offset(0, 1).Value & "<", MatchCase:=True
...

编辑: 我有一个大约 1000 个单词的列表,应该通过脚本运行,并单独替换。因此,我需要将案例维护为变量输入。 (如果匹配为Example,则替换为Replaced

编辑: 有几个特殊字符需要处理。例如:",./\"?();:&"。这个列表已经很长了。

【问题讨论】:

    标签: vba excel


    【解决方案1】:

    试试这段代码,不需要使用正则表达式:

    str = Cells(rowNumber, columnNumber).Value
    str = Replace(str, " example", " replaced")
    str = Replace(str, " Example", " Replaced")
    str = Replace(str, ">example", ">replaced")
    str = Replace(str, ">Example", ">Replaced")
    Cells(rowNumber, columnNumber).Value = str
    

    【讨论】:

    • 谢谢。但这不会解决这个例子:一个>example一个>replaced
    • @Rune 为什么不呢??
    • 因为前面的特殊字符">"不是空格
    • @Rune 只需像其他案例一样添加此案例 - 正如我在更新的答案中所做的那样。
    • 当然,但是有几个特殊字符需要处理。例如:",./\"?();:&"。这个列表已经很长了。
    【解决方案2】:

    或者使用正则表达式模式

    \b[E|e]xample\b
    

    正则表达式:

    Try it


    VBA:

    Option Explicit
    Public Sub test()
        Dim arr(), i As Long
        arr = Array("One dexamples string", "One example string", "One >example< string", "One Example, string", "One Example string", "One example string")
        For i = LBound(arr) To UBound(arr)
            Debug.Print ReplaceMatch(arr(i), "\b[E|e]xample\b")
        Next i
    End Sub
    Public Function ReplaceMatch(ByVal inputString As String, ByVal pattern As String) As String
        Dim re As Object
        Set re = CreateObject("VBScript.RegExp")
        With re
            .Global = True
            .MultiLine = True
            .pattern = pattern
    
            If .test(inputString) Then
                ReplaceMatch = .Replace(inputString, "replaced")
            Else
                ReplaceMatch = inputString
            End If
        End With
    End Function
    

    这需要对案例测试进行一些开发:

    Option Explicit
    
    Public Sub test()
        Dim arr(), i As Long
        arr = Array("One dexamples string", "One example string", "One >example< string", "One Example, string", "One Example string", "One example string")
        For i = LBound(arr) To UBound(arr)
          Debug.Print ReplaceMatch(arr(i), "\b[E|e]xample\b")
        Next i
    End Sub
    Public Function ReplaceMatch(ByVal inputString As String, ByVal pattern As String) As String
        Dim re As Object
        Set re = CreateObject("VBScript.RegExp")
        With re
            .Global = True
            .MultiLine = True
            .pattern = pattern
    
            If .test(inputString) Then
                If AscW(Left$(.Execute(inputString)(0), 1)) < 91 Then
                    ReplaceMatch = .Replace(inputString, "Replaced")
                Else
                    ReplaceMatch = .Replace(inputString, "replaced")
                End If
            Else
                ReplaceMatch = inputString
            End If
        End With
    End Function
    

    【讨论】:

    • 谢谢。这看起来很有希望。我有一个大约 1000 个单词的列表,应该通过脚本运行,并单独替换。因此,我需要将案例维护为变量输入。 (如果匹配为Example,则替换为Replaced
    • 抱歉,示例 = 已替换,示例 = 已替换?
    • 我修改了以上内容。它基于单个匹配检查,但很容易适应循环所有匹配。
    【解决方案3】:

    如果您的大写/小写可变性仅涉及单词的第一个字母,则以下代码将执行此操作。

    如果单词中的大小写可能混合,您将需要逐个字母循环,并且还要决定如果替换的长度与找到的单词的长度不同时该怎么办

    此代码的一个潜在问题:

    • \b 是一个字边界标记。
    • 单词边界定义为一侧由单词标记界定的位置,另一侧由非单词标记或字符串的开头/结尾界定。
    • 单词标记是[A-Za-z0-9_] 集合中的任何内容
    • 因此,如果您的源代码中有以 _(下划线)开头或结尾的字符串,则将找不到这些字符串。
    • 如果这可能是一个问题,我们将不得不更改正则表达式,以及在哪里查找“大小写”字符,或者只是暂时将下划线替换为其他非单词字符(然后再将其更改回来) .

    Option Explicit
    'Set reference to Microsoft VBScript Regular Expressions 5.5
    '   or use late binding
    Function CSReplace(S As String, sFind As String, sRepl As String) As String
        Dim RE As RegExp, MC As MatchCollection, M As Match
        Dim sTemp As String, I As Long
    
    Set RE = New RegExp
    With RE
        .Global = True
        .IgnoreCase = True
        .Pattern = "\b" & sFind & "\b"
        If .Test(S) = True Then
            Set MC = .Execute(S)
            sTemp = S
            For I = MC.Count - 1 To 0 Step -1
                Set M = MC(I)
                sRepl = LCase(sRepl)
                If Left(M, 1) = UCase(Left(M, 1)) Then _
                    sRepl = UCase(Left(sRepl, 1)) & Mid(sRepl, 2)
                sTemp = WorksheetFunction.Replace(sTemp, M.FirstIndex + 1, Len(sFind), sRepl)
            Next I
            CSReplace = sTemp
        Else
            CSReplace = S
        End If
    End With
    
    End Function
    

    【讨论】:

      猜你喜欢
      • 2018-07-13
      • 2017-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-30
      • 2021-11-29
      相关资源
      最近更新 更多