在分隔符 VBA 之间的整个字符串片段上查找替换

Find replace on the entire string fragments between delimiters VBA

我有管道分隔的字符串,我需要在管道之间的 entire 子字符串上查找和替换

所以如果我的字符串看起来像

AAAP|AAA TTT|AAA|000AAA|AAAP|AAA TTT|AAA|000AAA|AAAP|AAA TTT|AAA|AAA

AAA 可以在字符串中的任意位置。开始and/or结束或存在多次

我想用 ZZZ

替换 AAA

我需要的结果:

AAAP|AAA TTT|ZZZ|000ZZZ|AAAP|AAA TTT|ZZZ|000ZZZ|AAAP|AAA TTT|ZZZ|ZZZ

我得到的结果

AAAP|ZZZ TTT|ZZZ|000 ...

如何限制对整个子串的替换

Sub ExtractSubstringReplace()
Dim strSource, strReplace, strFind, RegExpReplaceWord, r, a

    strSource = "AAAP|AAA TTT|AAA|000"
    strFind = "AAA"
    strReplace = "ZZZ"
  
    Dim re As Object
    Set re = CreateObject("VBScript.RegExp")
    re.Global = True
    re.IgnoreCase = True
    re.Pattern = "\b" & strFind & "\b"
    RegExpReplaceWord = re.Replace(strSource, strReplace)
  
  MsgBox RegExpReplaceWord
  
End Sub

将要替换的字符串(AAAP|AAA TTT|AAA|000)放入Sheet1的A1单元格,运行输入以下代码。 您将获得在单元格 A2 中进行替换的整个字符串。

Sub ExtractSubstringReplace()
    Dim strArr, str, strArrNew(), strSource As String, strReplace As String, strFind As String, i As Long
    
    strSource = Sheet1.Range("A1").Value
    strFind = "AAA"
    strReplace = "ZZZ"
    
    strArr = Split(Sheet1.Range("A1").Value, "|")
    
    For Each str In strArr
        If str = strFind Then str = strReplace
        ReDim Preserve strArrNew(i)
        strArrNew(i) = str
        i = i + 1
    Next str
    
    For Each str In strArrNew
        Debug.Print str
    Next str
    
    Sheet1.Range("A2").Value = Join(strArrNew, "|")
    
End Sub

您可以使用

re.Pattern = "(^|\|)" & strFind & "(?![^|])"
RegExpReplaceWord = re.Replace(strSource, "" & strReplace)

参见(^|\|)AAA(?![^|])regex demo。注意它等于 (^|\|)AAA(?=\||$).

详情:

  • (^|\|) - 捕获第 1 组:字符串开头或管道字符
  • AAA - 搜索字符串
  • (?![^|]) / (?=\||$) - 确保在当前位置右侧紧邻 | 或字符串结尾的前瞻。

注意:如果您的 strFind 可以包含特殊的正则表达式元字符,请确保使用 .[=21= 中的解决方案对字符串进行转义]

我会选择@Siddharth Rout 评论中提供的选项,因为它可能是最有效的。

Sub Test()
    MsgBox ExtractSubstringReplace("AAAP|AAA TTT|AAA|000", "AAA", "ZZZ")
    MsgBox ExtractSubstringReplace("AAA|AAAP|AAA TTT|AAA|000", "AAA", "ZZZ")
    MsgBox ExtractSubstringReplace("AAA|AAAP|AAA TTT|AAA|AAA", "AAA", "ZZZ")
End Sub


Public Function ExtractSubstringReplace(ByVal strSource As String _
                                      , ByVal strFind As String _
                                      , ByVal strReplace As String _
                                      , Optional ByVal delimiter As String = "|" _
) As String
    Dim result As String
    
    'Duplicate delimiter and also add leading and trailing delimiter
    result = delimiter & Replace(strSource, delimiter, delimiter & delimiter) & delimiter
    'Replace substrings
    result = Replace(result, delimiter & strFind & delimiter, delimiter & strReplace & delimiter)
    'Remove leading and trailing delimiter that we added previously
    result = Mid$(result, Len(delimiter) + 1, Len(result) - Len(delimiter) * 2)
    'Restore delimiters
    ExtractSubstringReplace = Replace(result, delimiter & delimiter, delimiter)
End Function

您也可以在 Excel 单元格中使用该函数。

略微缩短代码

作为对@ChristianBuse 的优秀解决方案的补充,另一种基于相同想法的快速 方法(仅需要 0.00 到最多 0.02 秒):

Function SubRep(src, fnd, repl, Optional ByVal delim As String = "|") As String
    SubRep = delim & src & delim
    Dim i As Long
    For i = 1 To 2
        SubRep = Replace(SubRep, delim & fnd & delim, delim & repl & delim)
    Next
    SubRep = Mid$(SubRep, 2, Len(SubRep) - 2)
End Function

示例调用

Sub ExampleCall()
    Dim terms
    terms = Array("AAAP|AAA TTT|AAA|000", "AAA|AAAP|AAA TTT|AAA|000", "AAA|AAAP|AAA TTT|AAA|AAA")
    Dim i As Long
    For i = LBound(terms) To UBound(terms)
        Debug.Print Format(i, "0 ") & terms(i) & vbNewLine & "  " & _
            SubRep(terms(i), "AAA", "ZZZ")
    Next
End Sub

结果VB编辑器立即window

0 AAAP|AAA TTT|AAA|000
  AAAP|AAA TTT|ZZZ|000
1 AAA|AAAP|AAA TTT|AAA|000
  ZZZ|AAAP|AAA TTT|ZZZ|000
2 AAA|AAAP|AAA TTT|AAA|AAA
  ZZZ|AAAP|AAA TTT|ZZZ|ZZZ