VBA正则表达式仅返回最后一个匹配项

时间:2020-02-20 10:36:45

标签: regex vba ms-word

我正在尝试查找在括号内的引号中找到的所有词语的“ 所有”(“要查找的词条”),无论括号中是否有其他词(这也是“要找到的条款”。

我的ActiveDocument的内容是:

This is a ("Test") and another (second "Test2")

我的代码是:

Dim regEx As Object
Dim matchCollection As Object
Dim extractedString As String
Dim match As Object
Dim RealQ
Dim n As Integer

RealQ = Chr(34)

Set regEx = CreateObject("VBScript.RegExp")
With regEx
  .IgnoreCase = IgnoreCase
  .Global = True
  .MultiLine = True
  .Pattern = "\(.*" & RealQ & "(.*)" & RealQ & "\)"
End With

Set matchCollection = regEx.Execute(ActiveDocument.Content.Text)

extractedString = ""

For Each match In matchCollection

    Debug.Print (match.submatches(0))

Next

以上内容仅找到最后一次出现,即“ Test2”。我想念什么?

非常感谢!

2 个答案:

答案 0 :(得分:0)

您可以在Word本身中使用通配符搜索来执行此任务,而无需调用Regexp。下面的代码将返回一个范围对象的scripting.dictionary,您可以从中提取文本,或者通过很小的调整就可以返回捕获的文本。按键功能使您可以定义要使用的括号组,以及希望用于引号的字符。在下面的测试案例中,我使用了字符作为单词中的智能引号。

我使用的测试文字是

Blah blah blah (blah "Text 1" blah) blah blah blah Blah blah blah (blah “Text 2” blah) Blah blah blah (blah “Text 3” blah) Blah blah blah (blah “Text 4” blah)

哪个输出为

Text 2
Text 3
Text 4

因为第一组引号不是智能引号。您无需说是否只需要提取文本或查找文本,然后以某种方式在Word文档中对其进行处理,因此,我的第一选择是返回找到的文本的Word.Ranges。该函数的注释中提供了仅获取文本的调整。

下面的代码无需使用出色的RubberDuck插件进行代码检查。

Public Sub testGetTextInQuotesInBrackets()

Dim myTexts As Scripting.Dictionary

    Set myTexts = _
        GetTextInQuotesInBrackets _
        ( _
            "(,)", _
            ChrW$(&H201C) & "," & ChrW$(&H201D), _
            ActiveDocument.StoryRanges(wdMainTextStory) _
        )

    Dim myItem As Variant
    For Each myItem In myTexts

        Debug.Print myTexts.Item(myItem).Text
        ' if just the text was collected
        'Debug.Print myItem

    Next

End Sub

'@Description("Returns a scripting.Dictionary of long vs word.range objects)
Function GetTextInQuotesInBrackets _
( _
    ByVal ipBrackets As String, _
    ByVal ipQuotes As String, _
    ByRef ipRange As Word.Range _
) As Scripting.Dictionary


    Dim myTextRanges As Scripting.Dictionary
    Set myTextRanges = New Scripting.Dictionary

    Dim myBrackets As Variant
    myBrackets = Split(ipBrackets, ",")

    Dim myQuotes As Variant
    myQuotes = Split(ipQuotes, ",")

    With ipRange

        With .Find

            .ClearFormatting
            .Text = "[" & myBrackets(0) & "]*[" & myQuotes(0) & "]*[" & myQuotes(1) & "]" ' is there any need to process the following closing bracket
            .MatchWildcards = True
            .Wrap = wdFindStop

        End With

        Do While .Find.Execute

            Dim myFoundRange As Word.Range
            Set myFoundRange = .Duplicate
            With myFoundRange

                .MoveStartUntil cset:=myQuotes(0)
                ' Select the text within the quotes
                .MoveStart Count:=1
                .MoveEnd Count:=-1


            End With

            myTextRanges.Add myTextRanges.Count, myFoundRange
            ' Alternatively, if you just need the text
            'myTextRanges.add myTextRanges.count, myFoundRange.Text
            .Start = myFoundRange.End + 2
            .End = ipRange.End

        Loop

    End With

    Set GetTextInQuotesInBrackets = myTextRanges

End Function

答案 1 :(得分:0)

您不需要RegEx!可以使用Word自己的通配符查找工具完成所有操作。例如:

$(document).ready(function(){
$('.js-select2').on('change', function(){
alert("Hello! I am an alert box!");
});
});

更复杂的代码也可以用于处理带有智能引号的内容。

相关问题