1

我现在正在使用 Instr/Split 执行此操作,但发现正则表达式通常要快得多(这是一个内部循环,每次运行 100K+ 测试)。

一般形式为:

word0 = word1, word2, word3...  

的右侧有一个或多个单词=。一个词被定义为[\w.-]+。我还需要在任何时候允许空格。=是必需的。

我想只返回Matches 集合中的word1word2word3

=就是让我难过的地方。根据模式,我要么得到一个匹配项,要么没有一个匹配项。

这是一些测试代码。在第 17 行更改RE.Pattern以进行测试。

Option Explicit

Test1 "word1, word2",""
Test1 " word0 = word1, word.2  , word3.qrs_t-1", "word1 word.2 word3.qrs_t-1"
Test1 "word0=word1", "word1"

WScript.Quit

Sub Test1(TestString, CorrectOutput)

    Dim RE, Matches, Answer
    Dim i, j

    Set RE     = New RegExp
    RE.Global  = True

    RE.Pattern = "=([\w.-]+)"

    Set Matches = RE.Execute(TestString)

    Answer =  "Input:  " & vbTab & TestString & vbLf
    Answer = Answer & "Correct:" & vbTab & CorrectOutput & vbLf

    Answer = Answer &  "Actual: " & vbTab

    For i = 0 To Matches.Count -1
        If i > 0 Then
            Answer = Answer & " "
        End If
        Answer = Answer & Matches(i).value
    Next

    MsgBox Answer

End Sub
4

2 回答 2

0

使用以下正则表达式从输入字符串中提取带有单词列表的子字符串:

str = "..."

Set re = New RegExp
re.Pattern = "^.*?=((?:[^,]+)(?:,[^,]+)*)"
re.Global  = True

Set m = re.Execute(str)

然后使用第二个表达式删除分隔逗号并破坏空格:

Set re2 = New RegExp
re2.Pattern = "\s*,\s*"
re2.Global  = True

wordlist = ""
If m.Count > 0 Then
  wordlist = Trim(re2.Replace(m(0).SubMatches(0), " "))
End If

WScript.Echo wordlist
于 2013-05-18T12:21:53.513 回答
0

描述

试试这个,它会:

  • 在等号之前需要一个值
  • 需要一个等号
  • 等号后至少需要 1 个值
  • 返回 1 到 3 个逗号分隔的文本块中的每一个
  • 修剪所有返回值的空格

(?:^\s*?(\b[^=]*?\b)(?:\s{0,}[=]\s{0,}))(?:(['"]?)(\b[^,]*\b)\2\s*?)(?:$|(?:[,]\s*?(['"]?)(\b[^,]*\b)\4\s*?)(?:$|[,]\s*?(['"]?)(\b[^,]*\b)\6\s*?$))

在此处输入图像描述 (右键单击图像并选择在新选项卡或新窗口中查看完整尺寸)

团体

  • 如果有效,组 0 匹配完整的字符串
  • 1-7组
    1. 等号前的值
    2. 如果值 1 有一个,则引用分隔符
    3. 值列表中的第一个值
    4. 如果值 2 有一个,则引用分隔符
    5. 值列表中的第二个值
    6. 如果值为 3,则引用分隔符
    7. 值列表中的第三个值

VB.NET 代码示例演示正则表达式的工作原理

Imports System.Text.RegularExpressions
Module Module1
  Sub Main()
    Dim sourcestring as String = "replace with your source string"
    Dim re As Regex = New Regex("(?:^\s*?(\b[^=]*?\b)(?:\s{0,}[=]\s{0,}))(?:(['"]?)(\b[^,]*\b)\2\s*?)(?:$|(?:[,]\s*?(['"]?)(\b[^,]*\b)\4\s*?)(?:$|[,]\s*?(['"]?)(\b[^,]*\b)\6\s*?$))",RegexOptions.IgnoreCase OR RegexOptions.Multiline OR RegexOptions.Singleline)
    Dim mc as MatchCollection = re.Matches(sourcestring)
    Dim mIdx as Integer = 0
    For each m as Match in mc
      For groupIdx As Integer = 0 To m.Groups.Count - 1
        Console.WriteLine("[{0}][{1}] = {2}", mIdx, re.GetGroupNames(groupIdx), m.Groups(groupIdx).Value)
      Next
      mIdx=mIdx+1
    Next
  End Sub
End Module

$matches Array:
(
    [0] => Array
        (
            [0] =>  word0 = word1, word.2  , word3.qrs_t-1
        )

    [1] => Array
        (
            [0] => word0
        )

    [2] => Array
        (
            [0] => 
        )

    [3] => Array
        (
            [0] => word1
        )

    [4] => Array
        (
            [0] => 
        )

    [5] => Array
        (
            [0] => word.2
        )

    [6] => Array
        (
            [0] => 
        )

    [7] => Array
        (
            [0] => word3.qrs_t-1
        )

)
于 2013-05-18T05:03:23.417 回答