Word VBA 中的正则表达式没有返回正确的值

问题描述

我有在线测试的正则表达式,以确保它是正确的。当我在 MS Word 中使用它时,它返回的不仅仅是我想要的值。

这是正则表达式([nN][0-9].*-[tT].\S*[0-9])

这是我在 Word VBA 中使用的代码

 Dim regEx As VBScript_RegExp_55.RegExp
 Set regEx = New VBScript_RegExp_55.RegExp
 Dim Matches As Object
        
 With regEx
   .IgnoreCase = False
   .MultiLine = True
   .Global = True    ' Only look for 1 match; False is actually the default.
   .pattern = "([nN][0-9].*-[tT].\S*[0-9])"  ' Word separates lines with CR (\r)
 End With
 Set Matches = regEx.Execute(ActiveDocument.Content.Text)

这是我的word文档中的一个文本示例:

叫我以实玛利。几年前 - 别管多久了 - 我的钱包里几乎没有钱,也没什么特别的 在岸上引起我的兴趣,我想我会航行一点,看看 世界上有水的部分。这是我开车离开的一种方式 健脾,调经。每当我发现自己在成长 嘴巴严酷;每当我的 11 月潮湿多雨时 灵魂;每当我发现自己不由自主地停在棺材前 仓库,以及我遇到的每一个葬礼的后方;和 尤其是当我的低能占据了我的上风时,它 需要一个强有力的道德原则来防止我故意 走上街头,在方法论上敲人的帽子 关闭 - 那么,我认为是时候尽快出海了。 N1.2.3-T1-Test-4.5-S1
这是我的手枪和球的替代品... 我悄悄地上了船。这没有什么令人惊讶的。如果 但他们知道,几乎所有的人都在他们的学位,一段时间或其他, 珍惜与我几乎相同的对海洋的感情:

  1. 鲸鱼
  2. 鲨鱼
  3. 船舶

我想从文本中获取 N1.2.3-T1-Test-4.5-S1,但它返回以下内容

N1.2.3-T1-Test-4.5-S1 这是我的手枪和球的替代品...我 悄悄地上船。这没有什么令人惊讶的。如果他们 但我知道,几乎所有的人都在他们的学位,一段时间或其他, 珍惜与我几乎相同的对海洋的感情:

  1. 鲸鱼
  2. 鲨鱼
  3. 船舶

它从第一个找到的实例返回到文档的末尾,而不是匹配值的末尾。

我的文档可能有很多这种模式的实例:N1.2.3-T1-Test-4.5-S1,我需要逐一拉出。

我做错了什么?

以下是更改后的代码,但仍然无法正常工作:

    Dim regEx As VBScript_RegExp_55.RegExp
    Set regEx = New VBScript_RegExp_55.RegExp
    Dim Matches As VBScript_RegExp_55.matchCollection
    Dim Match As VBScript_RegExp_55.Match
    
    With regEx
        .IgnoreCase = False
        .MultiLine = True
        .Global = False    ' Only look for 1 match; False is actually the default.
        .pattern = "([nN][0-9].*-[tT].\S*[0-9])"  ' Word separates lines with CR (\r)
    End With
    Set Matches = regEx.Execute(ActiveDocument.Content.Text)
    For Each Match In Matches
        MsgBox (Match.value)
    Next Match

这是我的 msgBox显示内容

enter image description here

我用以下数据创建了一个简单的 word 文档,它给了我同样的问题:

叫我以实玛利。几年前 - 别管多久了 - 我的钱包里几乎没有钱,也没什么特别的 在岸上引起我的兴趣,我想我会航行一点,看看 世界上有水的部分。这是我开车离开的一种方式 健脾,调经。每当我发现自己在成长 嘴巴严酷;每当我的 11 月潮湿多雨时 灵魂;每当我发现自己不由自主地停在棺材前 仓库,以及我遇到的每一个葬礼的后方;和 尤其是当我的低能占据了我的上风时,它 需要一个强有力的道德原则来防止我故意 走上街头,在方法论上敲人的帽子 关闭 - 那么,我认为是时候尽快出海了。 N1.2.3-T1-Test-4.5-S1
这是我的手枪和球的替代品... 我悄悄地上了船。这没有什么令人惊讶的。如果 但他们知道,几乎所有的人都在他们的学位,一段时间或其他, 珍惜与我几乎相同的对海洋的感情:

  1. 鲸鱼
  2. 鲨鱼
  3. 船舶
    N1.2.3-T1-Test-4.5-S1
    N1.2.3-T1-Test-4.5-S1
    N1.2.3-T1-Test-4.5-S1
    N1.2.3-T1-Test-4.5-S1

如果我删除最后 4 个项目,它会起作用。

解决方法

RegEx.Execute 返回一个 MatchCollection,而不是一个 Match。试试这个:

Sub Test()

 Dim regEx As VBScript_RegExp_55.RegExp
 Set regEx = New VBScript_RegExp_55.RegExp
 Dim Matches As VBScript_RegExp_55.MatchCollection
 Dim Match As VBScript_RegExp_55.Match
        
 With regEx
   .IgnoreCase = False
   .MultiLine = True
   .Global = True    ' Only look for 1 match; False is actually the default.
   .Pattern = "([nN][0-9].*-[tT].\S*[0-9])"  ' Word separates lines with CR (\r)
 End With
 Set Matches = regEx.Execute(ActiveDocument.Content.Text)
 For Each Match In Matches
    Debug.Print Match.Value
 Next Match
 
End Sub
,

您不需要为此使用正则表达式 - 这一切都可以使用通配符在 Word 中查找:

Sub Demo()
With ActiveDocument.Range
  With .Find
    .ClearFormatting
    .Replacement.ClearFormatting
    .Text = "<[Nn][0-9].[0-9].[0-9]-[Tt]*[Ss][0-9]>"
    .Replacement.Text = ""
    .Forward = True
    .Wrap = wdFindStop
    .Format = False
    .MatchWildcards = True
  End With
  Do While .Find.Execute
    .Select
    MsgBox .Text
    .Collapse wdCollapseEnd
  Loop
End With
End Sub