2008-10-08 31 views
0

我有這樣的正則表達式.NET:正則表達式未能在右邊的括號

^(?<prefix>("[^"]*"))\s(?<attrgroup>(\([^\)]*\)))\s(?<suffix>("[^"]*"))$ 

它正確地匹配以下字符串:

"some prefix" ("attribute 1" "value 1") "some suffix" 
"some prefix" ("attribute 1" "value 1" "attribute 2" "value 2") "some suffix" 

它未能對...

"some prefix" ("attribute 1" "value (fail) 1") "some suffix" 

。由於「失敗」後的正確原因。

如何修改我的正則表達式,以便attrgroup匹配組最終會包含「("attribute 1" "value (fail) 1")」?我一直在看它太久,需要一些新鮮的眼睛。謝謝!

編輯:attrgroup將永遠不會包含除雙引號字符串對以外的任何內容。

+0

通過您的輸入規範,`attrgroup`是否包含除雙引號字符串之外的任何內容? – 2008-10-08 19:10:17

回答

2

我的,未經測試的猜測:

^(?<prefix>("[^"]*"))\s(?<attrgroup>(\(("[^"]*")(\s("[^"]*")*)**\)))\s(?<suffix>("[^"]*"))$ 

在此我把它換成

[^\)]* 

("[^"]*")(\s("[^"]*")*)* 

我假設括號內的一切是雙引號之間,或者是一個空白。

如果你想知道我是怎麼想出來的,請閱讀Mastering Regular Expressions

ps。如果我是正確的,那麼這也會將屬性組驗證爲引用字符串對。

1
^(?<prefix>"[^"]*")\s+(?<attrgroup>\(.*\))\s+(?<suffix>"[^"]*")$ 

給我修好了。

我刪除了多餘的未命名組,並簡化了屬性組(簡稱爲「任何字符」)。

一個非常值得投資的是JG Soft的使用RegexBuddy

編輯:這不會驗證屬性組作爲雙引號的字符串的,但應該/可以在一個獨立的正則表達式/驗證步驟來完成。

0

Hometoasts解決方案是一個很好的解決方案,雖然像任何自由的正則表達式,它應該只用於從源提取數據,你有一個合理的保證是正確的,而不是驗證。

0

如果不解決這個正則表達式的具體問題,我會推薦使用正則表達式工具來幫助構建,測試和驗證正則表達式。對於任何不平凡的東西,或者您可能需要維護/更新的表達式,這些工具都是必不可少的。

退房......

The Regex Coach - Lisp語言編寫的,一個年紀大一點,但我真的很喜歡這一個給他人。也許.NET更多的「現代」。有些人可能會喜歡這個。

0

我建議使用能夠處理這種結構的解析器。正則表達式失敗了,這是正確的,因爲你嘗試解析的語言看起來並不規則 - 至少從上面給出的例子來看。無論何時您需要識別嵌套,正則表達式都會失敗或成長爲如上所述的複雜動物。即使語言是經常性的,那裏的正則表達式對我來說看起來太複雜了。我寧願使用這樣的事情:

def parse_String(string): 
    index = skip_spaces(string, 0) 
    index, prefix = read_prefix(string, index) 
    index = skip_spaces(string, index) 
    index, attrgroup = read_attrgroup(string, index) 
    index = skip_spaces(string, index) 
    index, suffix = read_suffix(string, index) 
    return prefix, attrgroup, suffix 

def read_prefix(string, start_index): 
    return read_quoted_string(string, start_index) 

def read_attrgroup(string, start_index): 
    end_index, content = read_paren(string, start_index) 

    index = skip_spaces(content, 0) 
    index, first_entry = read_quoted_string(content, index) 
    index = skip_spaces(content, index) 
    index, second_entry = read_quoted_string(content, index) 
    return end_index, (first_entry, second_entry) 


def read_suffix(string, start_index): 
    return read_quoted_string(string, start_index) 

def read_paren(string, start_index): 
    return read_delimited_string(string, start_index, '(', ')') 

def read_quoted_string(string, start_index): 
    return read_delimited_string(string, start_index, '"', '"') 

def read_delimited_string(string, starting_index, start_limiter, end_limiter): 
    assert string[starting_index] == start_limiter, (start_limiter 
                +"!=" 
                +string[starting_index]) 
    current_index = starting_index+1 
    content = "" 
    while(string[current_index] != end_limiter): 
     content += string[current_index] 
     current_index += 1 

    assert string[current_index] == end_limiter 
    return current_index+1, content 

def skip_spaces(string, index): 
    while string[index] == " ": 
     index += 1 
    return index 

是的,這是更多的代碼,是的,按原始數字鍵,這需要更長的時間。但是 - 至少對我來說 - 我的解決方案更容易驗證。如果通過將所有這些移動到類中來解析字符串和索引配置文件,該類會在構造函數中解析這些字符串,這會增加更多。此外,很容易讓隱式空間跳過(使用一些只會跳過字符直到出現非空格的magic-next-char方法,除非由於字符串而處於某種非跳過模式,此模式可以設置爲例如,分隔函數)。這將打開parse_string到:

def parse_string(string): 
    prefix = read_prefix() 
    attrgroup = read_attr_group() 
    suffix = read_suffix() 
    return prefix, attrgroup, suffix. 

此外,這種功能可以擴展更容易覆蓋更復雜的表達式。任意嵌套attrgroups?改變一行代碼。嵌套parens?多一點工作,但沒有真正的問題。

現在,請火焰和downvote我成爲一些正則表達式異端和一些解析器倡導者。 > :)

PS:是的,該代碼是未經測試的。就我所知,我有3個錯別字,我沒有看到。