使用 Textrange.replace 时未保持区分大小写
Case sensitivity not maintained while using Textrange.replace
我希望一切都好..
我一直在尝试开发一个小宏,它可以从 PowerPoint 演示文稿中找到某些单词,并使用方法
将它们替换为某些其他单词
TextRange.Replace(FindWhat:=FindString, Replacewhat:=ReplaceString, _
WholeWords:=True, MatchCase := False)
要求是ReplaceString要和演示文稿中要替换的词一样区分大小写。但是使用上述方法,ReplaceString 的大小写始终保持不变(如前所述)。我需要根据演示文稿中 FindString 的情况更改它。
比如我的FindString是bridge,ReplaceString是brg,在我的演示中,如果出现Bridge和BRIDGE,就应该分别替换成Brg和BRG(但是上面的方法是替换Bridge和BRIDGE与 brg)
我希望我的查询有些道理..
谁能帮我解决这个问题?
谢谢
问候
我认为你可以做到这一点,但不能用 .Replace
。有必要将查找和替换的步骤分开,这样您就可以在两者之间检查找到的内容,然后用类似的文本大小写替换(例如 upper、lower 或 'proper')。
关键是使用InStr函数,因为它可以让你用任何文本大小写进行查找,同时还可以让你设置查找起始索引和return匹配的索引found - 这样您就可以循环遍历每场比赛,一次一场。然后,找到文本大小写,循环遍历匹配的每个字符,计算上下;并相应地替换。
Public Function ReplaceMatchCase(str, find, replace) As String
Dim lenStr As Long
Dim lenFind As Long
Dim i As Long
Dim j As Long
Dim countUpper As Long
Dim countLower As Long
Dim chr As String
i = 1
lenStr = Len(str)
lenFind = Len(find)
If lenFind = 0 Or lenStr = 0 Or lenStr < lenFind Then
ReplaceMatchCase = str
Exit Function
End If
'Loop through each match
Do
i = InStr(i, str, find, vbTextCompare)
If i = 0 Then
Exit Do
End If
countUpper = 0
countLower = 0
'Loop through chars in each match
For j = i To i + lenFind - 1
chr = Mid(str, j, 1)
If chr = UCase(chr) Then
countUpper = countUpper + 1
Else
countLower = countLower + 1
End If
Next j
'Replace
If countUpper <> 0 And countLower = 0 Then
'Uppercase
str = Mid(str, 1, i - 1) & UCase(replace) & Mid(str, i + lenFind)
ElseIf countUpper = 0 And countLower <> 0 Then
'Lowercase
str = Mid(str, 1, i - 1) & LCase(replace) & Mid(str, i + lenFind)
Else
'Mixed - assume 'proper' case - can change this according to need
str = Mid(str, 1, i - 1) & UCase(Mid(replace, 1, 1)) & LCase(Mid(replace, 2)) & Mid(str, i + lenFind)
End If
Loop While i <> 0
ReplaceMatchCase = str
End Function
您可以这样测试函数:
Sub Test()
Debug.Print ReplaceMatchCase("I walked to the furthest bridge and on the way I passed the first BRIDGE and the second Bridge.", "Bridge", "Brg")
End Sub
'I walked to the furthest brg and on the way I passed the first BRG and the second Brg.
在 PowerPoint 中,您可以像这样使用函数:
TextRange.Text = ReplaceMatchCase(TextRange.Text, FindString, ReplaceString)
这是一个简单的例子。在尝试任何替换之前,它会检查是否在文本范围内找到了这个词:这应该可以解决您的一些性能问题。具有能够使用 WholeWords:=True
的优点,它可以防止替换较长单词的子字符串。
Sub Tester()
Dim tr As TextRange
Set tr = ActivePresentation.Slides(1).Shapes(1).TextFrame.TextRange
DoReplace tr, "bridge", "brg"
End Sub
Sub DoReplace(tr As TextRange, findThis, replaceWith)
If InStr(1, tr.Text, findThis, vbTextCompare) > 0 Then 'is the word found at all?
'found at least one case form - just try to replace any case form found...
tr.Replace findWhat:=LCase(findThis), Replacewhat:=LCase(replaceWith), _
WholeWords:=True, MatchCase:=True
tr.Replace findWhat:=UCase(findThis), Replacewhat:=UCase(replaceWith), _
WholeWords:=True, MatchCase:=True
tr.Replace findWhat:=StrConv(findThis, vbProperCase), _
Replacewhat:=StrConv(replaceWith, vbProperCase), _
WholeWords:=True, MatchCase:=True
End If
End Sub
我希望一切都好.. 我一直在尝试开发一个小宏,它可以从 PowerPoint 演示文稿中找到某些单词,并使用方法
将它们替换为某些其他单词TextRange.Replace(FindWhat:=FindString, Replacewhat:=ReplaceString, _
WholeWords:=True, MatchCase := False)
要求是ReplaceString要和演示文稿中要替换的词一样区分大小写。但是使用上述方法,ReplaceString 的大小写始终保持不变(如前所述)。我需要根据演示文稿中 FindString 的情况更改它。
比如我的FindString是bridge,ReplaceString是brg,在我的演示中,如果出现Bridge和BRIDGE,就应该分别替换成Brg和BRG(但是上面的方法是替换Bridge和BRIDGE与 brg)
我希望我的查询有些道理..
谁能帮我解决这个问题?
谢谢 问候
我认为你可以做到这一点,但不能用 .Replace
。有必要将查找和替换的步骤分开,这样您就可以在两者之间检查找到的内容,然后用类似的文本大小写替换(例如 upper、lower 或 'proper')。
关键是使用InStr函数,因为它可以让你用任何文本大小写进行查找,同时还可以让你设置查找起始索引和return匹配的索引found - 这样您就可以循环遍历每场比赛,一次一场。然后,找到文本大小写,循环遍历匹配的每个字符,计算上下;并相应地替换。
Public Function ReplaceMatchCase(str, find, replace) As String
Dim lenStr As Long
Dim lenFind As Long
Dim i As Long
Dim j As Long
Dim countUpper As Long
Dim countLower As Long
Dim chr As String
i = 1
lenStr = Len(str)
lenFind = Len(find)
If lenFind = 0 Or lenStr = 0 Or lenStr < lenFind Then
ReplaceMatchCase = str
Exit Function
End If
'Loop through each match
Do
i = InStr(i, str, find, vbTextCompare)
If i = 0 Then
Exit Do
End If
countUpper = 0
countLower = 0
'Loop through chars in each match
For j = i To i + lenFind - 1
chr = Mid(str, j, 1)
If chr = UCase(chr) Then
countUpper = countUpper + 1
Else
countLower = countLower + 1
End If
Next j
'Replace
If countUpper <> 0 And countLower = 0 Then
'Uppercase
str = Mid(str, 1, i - 1) & UCase(replace) & Mid(str, i + lenFind)
ElseIf countUpper = 0 And countLower <> 0 Then
'Lowercase
str = Mid(str, 1, i - 1) & LCase(replace) & Mid(str, i + lenFind)
Else
'Mixed - assume 'proper' case - can change this according to need
str = Mid(str, 1, i - 1) & UCase(Mid(replace, 1, 1)) & LCase(Mid(replace, 2)) & Mid(str, i + lenFind)
End If
Loop While i <> 0
ReplaceMatchCase = str
End Function
您可以这样测试函数:
Sub Test()
Debug.Print ReplaceMatchCase("I walked to the furthest bridge and on the way I passed the first BRIDGE and the second Bridge.", "Bridge", "Brg")
End Sub
'I walked to the furthest brg and on the way I passed the first BRG and the second Brg.
在 PowerPoint 中,您可以像这样使用函数:
TextRange.Text = ReplaceMatchCase(TextRange.Text, FindString, ReplaceString)
这是一个简单的例子。在尝试任何替换之前,它会检查是否在文本范围内找到了这个词:这应该可以解决您的一些性能问题。具有能够使用 WholeWords:=True
的优点,它可以防止替换较长单词的子字符串。
Sub Tester()
Dim tr As TextRange
Set tr = ActivePresentation.Slides(1).Shapes(1).TextFrame.TextRange
DoReplace tr, "bridge", "brg"
End Sub
Sub DoReplace(tr As TextRange, findThis, replaceWith)
If InStr(1, tr.Text, findThis, vbTextCompare) > 0 Then 'is the word found at all?
'found at least one case form - just try to replace any case form found...
tr.Replace findWhat:=LCase(findThis), Replacewhat:=LCase(replaceWith), _
WholeWords:=True, MatchCase:=True
tr.Replace findWhat:=UCase(findThis), Replacewhat:=UCase(replaceWith), _
WholeWords:=True, MatchCase:=True
tr.Replace findWhat:=StrConv(findThis, vbProperCase), _
Replacewhat:=StrConv(replaceWith, vbProperCase), _
WholeWords:=True, MatchCase:=True
End If
End Sub