我有一列代码列表,如下所示。
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()
语句执行此操作?
如果没有,我将如何实现这一目标呢?模式匹配非常复杂,我甚至不想在没有正则表达式的情况下考虑这样做。
[我有一个解决方案,我在下面发布,但是我希望有人可以提出更简单的方法。]
答案 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
我希望这有帮助!