如何排除引号内找到的内容

时间:2015-12-30 20:27:49

标签: vba ms-word word-vba

我有以下功能,但是当我调用它时,我不希望它替换引号内的任何内容:

Function AutoReplace(source As String, typeText As String)
    Selection.Find.ClearFormatting
    Selection.Find.Replacement.ClearFormatting
    With Selection.Find
        .Text = Trim(source)
        .Replacement.Text = typeText
        .Forward = True
        .Wrap = wdFindContinue
    End With
    Selection.Find.Execute Replace:=wdReplaceAll
End Function

1 个答案:

答案 0 :(得分:1)

不幸的是,通配符搜索无法解决此问题,因此需要使用代码解决方案。

这方面的困难在于确定搜索词何时在引号内。当然,搜索词可以在一组引号中多次出现。我试图考虑所有排列,包括该术语是否出现在文档的开头/结尾,但我不能保证我抓住了所有这些排列......

我建议的方法的诀窍是比较找到的术语的文本中的位置,之前的开头报价,如果找到这些,则先前的结束报价是否跟随或先于打开报价。如果未找到任何开盘报价,则该术语显然不在引号中。如果收盘价低于开盘价,则该术语不在引号中。否则,它假定引号是成对的,并且该术语确实在引号内。

编码可能更优雅(嵌套级别更少),但我没有为此付费,所以我把它留给任何想要使用它的人......

Sub FindTermNotInQuotes()
  Dim sTerm As String, sReplacement As String
  Dim sOpenQuote As String, sCloseQuote As String
  Dim rngSearch As word.Range, rngOpenQuote As word.Range
  Dim rngTerm As word.Range, rngCloseQuote As word.Range
  Dim bFound As Boolean, rngFound As word.Range

  sTerm = "can't"
  sReplacement = "cannot"
  sOpenQuote = Chr(147)
  sCloseQuote = Chr(148)
  Set rngSearch = ActiveDocument.content
  Set rngFound = ActiveDocument.Range(2)
  Do
    With rngSearch.Find
      'Keep previous location so that we can check
      'If searching the open quote is a previous one
      rngFound.Collapse wdCollapseStart
      .ClearFormatting
      .Text = sTerm
      .Forward = True
      bFound = .Execute
      If bFound Then
        Set rngOpenQuote = rngSearch.Duplicate
        rngOpenQuote.Start = ActiveDocument.content.Start
        With rngOpenQuote.Find
            .Text = sOpenQuote
            .Forward = False
            If .Execute Then
                If rngOpenQuote.Start < rngFound.Start Then
                    'This quote is in front of the previous "hit"
                    'So we need to check if there's a closing quote
                    Set rngCloseQuote = rngSearch.Duplicate
                    rngCloseQuote.Start = ActiveDocument.content.Start
                    With rngCloseQuote.Find
                        .Text = sCloseQuote
                        .Forward = False
                        If .Execute Then
                            'It's not in a quote
                            If rngCloseQuote.Start > rngOpenQuote.Start Then
                                'If close quote is before open quote
                                'then the term is still within quotes
                                rngSearch.Text = sReplacement
                            End If
                        End If
                    End With
                End If
            End If
        End With
      End If
      Set rngFound = rngSearch.Duplicate
      rngSearch.Collapse wdCollapseEnd
      rngSearch.End = ActiveDocument.content.End
    End With
  Loop While bFound
End Sub