2011-03-22 74 views
0

嗨我想要一個正則表達式模式來匹配一個非常特定的字符串語法。下面是我放在一起的模式字符串;它工作在某些情況下,而不是在別人,我很肯定這是太過於複雜:正則表達式來匹配特定的語法

 
\[\CONTENT\((?:(?:(?:(\w+) ?= ?((?:"(?:[^"]+)")|(?:'(?:[^']+)')|(?:(?:[^"',]+))) ?, ?)+(?:(?:\w+) ?= ?(?:(?:"(?:.+)")|(?:'(?:.+)')|(?:(?:[^"',]+)))))|(?:(?:\w+) ?= ?(?:(?:"(?:.+)")|(?:'(?:.+)')|(?:(?:[^"',]+)))))\)]

,我試圖匹配的字符串語法如下:

 
[CONTENT(Name="value, Name2='value2', Name_3 = value3, Name4= "value 4 \" includes an escaped quote")] etc 

的正賽團體我想返回如下

 
Match Group 1 - Match 1: [CONTENT(Name="value", Name2='value2', Name_3 = value3, Name4= "value 4 \" includes an escaped quote")] 

Match Group 2 - Match 1: Name="value" 
Match Group 2 - Match 2: Name 
Match Group 2 - Match 3: value 

Match Group 3 - Match 1: Name2='value' 
Match Group 3 - Match 2: Name2 
Match Group 3 - Match 3: value2 

Match Group 4- Match 1: Name_3 = value3 
Match Group 4- Match 2: Name_3 
Match Group 4- Match 3: value3 

Match Group 5 - Match 1: Name4= "value 4 \" includes an escaped quote" 
Match Group 5 - Match 2: Name4 
Match Group 5 - Match 3: value 4 \" includes an escaped quote 

當我指的是符合我指的是比賽團體組.NET。結果不必如上所述,但如果可能的話,結果相似。

我很好用簡單的正則表達式,但我不能讓我的頭繞着周圍等。「名稱=值」集可以重複許多(可能,但不太可能無限的時間)每個由'分隔, '(逗號) - 除最後一組外(最後一個名字/數值組不會跟着一個','(逗號))。 '='(等於)符號(或不)以及','(逗號)的任一側都可以有空格。

我不知道這是不是太複雜用正則表達式或做什麼(如果我接受任何建議,任何人都可以給關於如何分析這樣的字符串替代。)

感謝任何人都可以提供的幫助。

Chris

+0

您的示例數據中的第一個attrib/value對讀取:'Name =「value,'(該值缺少結尾引用),最後一個屬性/值對具有適當引用的值,其中包含轉義引用。是第一個缺少近似引用錯字? – ridgerunner 2011-03-22 17:13:25

+0

,這是很多不必要的非捕獲組。 – 2011-03-22 19:47:40

回答

1

假設...

  1. 必須有至少一個ATTRIB /值對。 AND
  2. 每個attrib/value對由一個逗號和可選空白分隔。 AND
  3. 每個屬性值都是正確引用的字符串或單個「單詞」。 AND
  4. 引用的屬性值字符串可能包含轉義字符:(例如v1="That's not \"MY\" problem!"和/或v2='That\'s not "MY" problem!')。 AND
  5. 屬性名稱或非引號值「word」僅包含字母和短劃線(即[A-Za-z0-9_\-]+)。 (請注意,原來的問題沒有明確界定這一要求。)

然後這個表達式(在C#)將正確匹配[CONTENT(a1=v1, a2=v2...)]結構:

Regex regexObj = new Regex(
    @"# Match a [CONTENT(a1=v1, a2=v2...)] structure. 
    \[CONTENT\(\s*     # Opening delimiter 
    # Match required first attrib/value pair. 
    [\w\-]+       # First attrib name (Allow [A-Z-a-z0-9_-]. 
    \s*=\s*       # Name and value separated by =. 
    (?:        # Group value spec alternatives. 
     ""[^""\\]*(\\.[^""\\]*)*"" # Either double quoted string, 
    | '[^'\\]*(\\.[^'\\]*)*'  # or a single quoted string, 
    | [\w\-]+      # or single unquoted ""word"". 
    )        # End group for value alternatives. 
    # Match optional second, third... attrib/value pairs. 
    (?:        # Group to allow optional pairs. 
     \s*,\s*      # All pairs separated by comma. 
     [\w\-]+      # Attrib name. 
     \s*=\s*      # Name and value separated by =. 
     (?:       # Group value spec alternatives. 
     ""[^""\\]*(\\.[^""\\]*)*"" # Either double quoted string, 
     | '[^'\\]*(\\.[^'\\]*)*'  # or a single quoted string, 
     | [\w\-]+     # or single unquoted ""word"". 
    )        # End group for value alternatives. 
    )*        # Zero or more optional A=V pairs. 
    \s*\)\]       # Closing delimiter.", 
    RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace); 

一旦匹配並抓獲單個[CONTENT(...)]結構,您可以使用另一個匹配每個atrib /值對的正則表達式分開挑選它,一次一個。

而且爲了善良,在編寫像這樣的非平凡正則表達式時,始終使用使用自由間距模式並添加註釋和縮進!

+0

非常感謝,完美的作品。 – Neaox 2011-03-23 11:18:06

0

這當然不是正則表達式。改爲使用合適的解析器 - 使用C#中的組合器解析遞歸下降解析器非常容易。例如,請參閱thisthis