【问题标题】:How to change case of matching letter with a VBA regex Replace?如何用 VBA 正则表达式替换匹配字母的大小写?
【发布时间】:2014-05-31 18:21:15
【问题描述】:

我有一列代码列表,如下所示。

2.A.B, 1.C.D, A.21.C.D, 1.C.D.11.C.D
6.A.A.5.F.A, 2.B.C.H.1
8.ABC.B, A.B.C.D
12.E.A, 3.NO.T
A.3.B.C.x, 1.N.N.9.J.K

我想查找由句点分隔的两个单个大写字母的所有实例,但只查找小于 6 的数字。我想删除字母之间的句点并将第二个字母转换为小写。期望的输出:

2.Ab, 1.Cd, A.21.C.D, 1.Cd.11.C.D
6.A.A.5.Fa, 2.Bc.H.1
8.ABC.B, A.B.C.D
12.E.A, 3.NO.T
A.3.Bc.x, 1.Nn.9.J.K

我在 VBA 中有以下代码。

Sub fixBlah()
Dim re As VBScript_RegExp_55.RegExp
Set re = New VBScript_RegExp_55.RegExp
re.Global = True
re.Pattern = "\b([1-5]\.[A-Z])\.([A-Z])\b"
For Each c In Selection.Cells
    c.Value = re.Replace("$1$2")
Next c
End Sub

这将删除句点,但不处理小写要求。我知道在其他风格的正则表达式中,我可以使用类似的东西

re.Replace("$1\L$2\E")

但这在 VBA 中没有预期的效果。我尝试使用谷歌搜索此功能,但找不到任何东西。有没有办法通过 VBA 中的简单 re.Replace() 语句来做到这一点?

如果不是,我将如何实现这一目标?模式匹配非常复杂,我什至不想考虑在没有正则表达式的情况下这样做。

[我想出了一个解决方案,贴在下面,但我希望有人能想出更简单的方法。]

【问题讨论】:

    标签: regex vba excel


    【解决方案1】:

    这是一种解决方法,它使用每个单独的正则表达式匹配的属性来使 VBA Replace() 函数仅替换匹配中的文本,而不替换其他任何内容。

    Sub fixBlah2()
    Dim re As VBScript_RegExp_55.RegExp, Matches As VBScript_RegExp_55.MatchCollection
    Dim M As VBScript_RegExp_55.Match
    Dim tmpChr As String, pre As String, i As Integer
    Set re = New VBScript_RegExp_55.RegExp
    re.Global = True
    re.Pattern = "\b([1-5]\.[A-Z])\.([A-Z])\b"
    For Each c In Selection.Cells
        'Count of number of replacements made. This is used to adjust M.FirstIndex
        '    so that it still matches correct substring even after substitutions.
        i = 0
        Set Matches = re.Execute(c.Value)
        For Each M In Matches
            tmpChr = LCase(M.SubMatches.Item(1))
            If M.FirstIndex > 0 Then
                pre = Left(c.Value, M.FirstIndex - i)
            Else
                pre = ""
            End If
            c.Value = pre & Replace(c.Value, M.Value, M.SubMatches.Item(0) & tmpChr, _ 
                      M.FirstIndex + 1 - i, 1)
            i = i + 1
        Next M
    Next c
    End Sub
    

    由于我不太明白的原因,如果您在Replace() 中指定起始索引,则输出也会从该索引开始,因此pre 变量用于捕获获取的字符串的第一部分被Replace 函数截断。

    【讨论】:

      【解决方案2】:

      所以这个问题很老,但我确实有另一种解决方法。可以这么说,我使用双正则表达式,第一个引擎将匹配项查找为执行,然后我循环遍历这些项目中的每一项并替换为小写版本。例如:

      Sub fixBlah()
      Dim re As VBScript_RegExp_55.RegExp
      dim ToReplace as Object
      Set re = New VBScript_RegExp_55.RegExp
      for each c in Selection.Cells
      with re      `enter code here`
        .Global = True
        .Pattern = "\b([1-5]\.[A-Z])\.([A-Z])\b"
        Set ToReplace = .execute(C.Value)
      end with
      
       'This generates a list of items that match.  Now to lowercase them and replace
       Dim LcaseVersion as string
       Dim ItemCt as integer
       for itemct = 0 to ToReplace.count - 1
       LcaseVersion = lcase(ToReplace.item(itemct))
            with re      `enter code here`
        .Global = True
        .Pattern = ToReplace.item(itemct)  'This looks for that specific item and replaces it with the lowercase version
        c.value = .replace(C.Value, LCaseVersion)
      end with
      End Sub
      

      我希望这会有所帮助!

      【讨论】:

        猜你喜欢
        • 2018-04-07
        • 2011-03-15
        • 1970-01-01
        • 1970-01-01
        • 2016-05-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-16
        相关资源
        最近更新 更多