2

我有一些输出到 RichTextBox(可能很多或很少,它的搜索结果)并且想应用一些自定义颜色编码。决定用 Regex 来做,虽然它可以工作,但对于 300 个结果来说似乎很慢(~20 秒)。

输出始终采用相同的格式:

Attribute1=Value1 Attribute2=(Value2) Attribute3="String value 3" Attribute4=

等等。所以,我有 4 种情况: stuff=stuff, stuff=(stuff) stuff="string of stuff" 和 stuff=

以下正则表达式可以正常工作(匹配它应该匹配的所有内容),但速度很慢:

(\S+)=("(?:[^"]|(?<open>")|(?<-open>"))+(?(open)(?!))")|(\S+)=(\((?:[^()]|(?<open>\()|(?<-open>\)))+(?(open)(?!))\))|(\S+)=(\S+)|(\S+)=\s

你们有没有看到什么特别让它减慢了速度?我敢肯定你会说,第一部分匹配引号,第二部分匹配括号,等等。

更新 开个玩笑,并没有完全返回我想要的......这个:

Attribute1=Value1 Attribute2=(Value2) Attribute3="String value 3" Attribute4= Attribute5="Another string"

返回这个:

5: Attribute1
6: Value1
3: Attribute2
4: (Value2)
1: Attribute3
2: "String value 3" Attribute4= Attribute5="Another string"

看起来引号一直匹配到第二个字符串,而不是单独考虑它们。

4

2 回答 2

8

描述

你的正则表达式有很多回溯,我只是为另一个问题写了一个这样的正则表达式。考虑以下通用正则表达式的 powershell 示例。

(?:\s|^)([^=]*)(?:=?["(]?([^)"]*?)[")]?)?(?=\s[^=\s]*=|$)

例子

    $Matches = @()
    $String = 'Attribute1=Value1 Attribute2=(Value2) Attribute3="String value 3" Attribute4= Attribute8=Value8 Attribut5=(Value5) Attribute6="String value 6" Attribute7='
    $Regex = '(?:\s|^)([^=]*)(?:=?["(]?([^)"]*?)[")]?)?(?=\s[^=\s]*=|$)'

Write-Host start with 
    write-host $String
    Write-Host
    Write-Host found
    ([regex]"(?i)$Regex").matches($String) | foreach {
        write-host "key at $($_.Groups[1].Index) = '$($_.Groups[1].Value)'`t= value at $($_.Groups[2].Index) = '$($_.Groups[2].Value)'"
        } # next match

产量

start with
Attribute1=Value1 Attribute2=(Value2) Attribute3="String value 3" Attribute4= Attribute8=Value8 Attribut5=(Value5) Attribute6="String value 6" Attribute7=

found
key at 0 = 'Attribute1' = value at 11 = 'Value1'
key at 18 = 'Attribute2'    = value at 30 = 'Value2'
key at 38 = 'Attribute3'    = value at 50 = 'String value 3'
key at 66 = 'Attribute4'    = value at 77 = ''
key at 78 = 'Attribute8'    = value at 89 = 'Value8'
key at 96 = 'Attribut5' = value at 107 = 'Value5'
key at 115 = 'Attribute6'   = value at 127 = 'String value 6'
key at 143 = 'Attribute7'   = value at 154 = ''

概括

在此处输入图像描述

  • (?:\s|^)非捕获以确保我们位于字符串或子字符串的开头
  • ([^=]*)捕获第一个等号之前的所有非等号字符
  • (?:启动非捕获块
  • =?使用等号(如果存在)
  • ["(]?使用引号或打开圆括号(如果存在)
  • ([^)"]*?)捕获所有非右圆括号和非引号字符,直到
  • [")]?使用引号或右圆括号(如果存在)
  • )?关闭非捕获块,并使这部分不需要
  • (?=启动一个零断言块以确保我们不会进入下一个键/值集
  • \s[^=\s]*=此块必须有一个空格,后跟非空格和非等号字符
  • |或者
  • $字符串的结尾,以确保我们可以捕获字符串中的最后一个键/值集
  • )关闭零断言块
于 2013-05-13T19:29:52.460 回答
2

你可以试试这个模式:

(?<attr>(?>\w+))=(?<val>(?>"(?>[^"]*)"|\((?>[^)]+)\)|(?>\S+)|(?=(?>\s\w+=|$))))
于 2013-05-13T19:44:45.010 回答