如何用VBA正则表达式替换匹配字母的大小写?

时间:2014-04-16 18:03:02

标签: regex vba excel-vba excel

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

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()语句执行此操作?

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

[我有一个解决方案,我在下面发布,但是我希望有人可以提出更简单的方法。]

2 个答案:

答案 0 :(得分:0)

这是一种解决方法,它使用每个单独的正则表达式匹配的属性来使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函数剪掉的字符串的一部分。

答案 1 :(得分:0)

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

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

我希望这有帮助!