這是醜陋的正則表達式模式。我相信它會運作良好。我已經嘗試了每個我能想到的病理學示例,包括包含語法錯誤的行。例如,引用的字符串含有太多的引號或太少,或者具有雙重轉義引號,因此,而不是轉義。並且在評論中引用了字符串,在我想提醒自己可以選擇時,我已經知道這些字符串。
,它絆倒了唯一的一次是,如果有一個看似引號字符串中雙斜槓,不知何故該字符串格式錯誤,雙斜槓合法結束的正確引用部分的外側。在語法上,它使得它成爲一個有效的評論,儘管不是程序員的意圖。所以,從程序員的角度來看,這是錯誤的,但根據規則,這真的是一個評論。意思是,這種模式似乎只是絆倒了。
使用時,模式將返回行的非註釋部分。該模式中有一個換行\n
以允許將其應用於整個文件。如果您的系統以某種其他方式解釋換行符,例如\r
或\r\n
,則可能需要修改。要在單行模式下使用它,如果您選擇,可以將其刪除。多行版本中的字符是17和18中的一行,並且是第五行,第六和第七個打印字符。但是,您可以放心地將其留在那裏,但是,與單行模式不同的是,它在多行模式下會返回一行換行符,換行符爲空白,或者在第一列開始註釋。如果將結果寫入新文件,這將保持原始版本和規定版本中的行號相同。使比較容易。
一個主要警告此模式:它使用一個分組構造,在正則表達式引擎中具有不同程度的支持。我相信在這裏使用,看看,只有.NET和PCRE引擎纔會接受YMMV。這是一種高等教育類型:(?(_condition_)_then_|_else_)
。 _condition_
模式被視爲零寬度斷言。如果模式匹配,則在嘗試匹配中使用_then_
模式,否則使用_else_
模式。如果沒有這種構造,這個模式就會變得不尋常,並且在我的一些病理測試案例中仍然沒有成功。
這裏介紹的模式是因爲它需要由正則表達式引擎來看。我是而不是是C#程序員,所以我不知道轉義引用字符串的所有細微差別。將這個模式放入你的代碼中,這樣所有的反斜槓和引號都可以被正則表達式引擎正確地看到。也許C#與Perl的heredoc
語法相同。
這是使用一線狀圖案:
^((?:(?:(?:[^"'/\n]|/(?!/))*)(?("(?=(?:\\\\|\\"|[^"])*"))(?:"(?:\\\\|\\"|[^"])*")|(?('(?=(?:\\\\|\\'|[^'])*'))(?:'(?:\\\\|\\'|[^'])*')|(?(/)|.))))*)
如果你想使用忽略模式空白選項,您可以使用此版本:
(?x) # Turn on the ignore white space option
^(# Start the only capturing group
(?: # A non-capturing group to allow for repeating the logic
(?: # Capture either of the two options below
[^"'/\n] # Capture everything not a single quote, double quote, a slash, or a newline
| # OR
/(?!/) # Capture a slash not followed by a slash [slash an negative look-ahead slash]
)* # As many times as possible, even if none
(?(" # Start a conditional match for double-quoted strings
(?=(?:\\\\|\\"|[^"])*") # Followed by a properly closed double-quoted string
) # Then
(?:"(?:\\\\|\\"|[^"])*") # Capture the whole double-quoted string
| # Otherwise
(?(' # Start a conditional match for single-quoted strings
(?=(?:\\\\|\\'|[^'])*') # Followed by a properly closed single-quoted string
) # Then
(?:'(?:\\\\|\\'|[^'])*') # Capture the whole double-quoted string
| # Otherwise
(?([^/]) # If next character is not a slash
.) # Capture that character, it is either a single quote, or a double quote not part of a properly closed
) # end the conditional match for single-quoted strings
) # End the conditional match for double-quoted strings
)* # Close the repeating non-capturing group, capturing as many times as possible, even if none
) # Close the only capturing group
這使你的代碼來解釋這個怪物,這樣當其他人看着它時,或者在幾個月內你必須自己處理它時,就沒有WTF時刻。我認爲這些評論可以很好地解釋它,但隨意以任何方式改變它們。
如上所述,條件匹配分組的支持有限。它會失敗的一個地方是您在之前的評論中鏈接到的網站。由於您使用的是C#,因此我選擇在.NET Regex Tester中執行測試,該測試可以處理這些構造。它也包含一個很好的參考。鑑於正確的選擇,您可以測試以上任一版本,並進行實驗。考慮到它的複雜性,我建議在某處測試它,以對照來自文件的數據,以及任何你可以想象的邊緣病例和病理測試。
只是爲了兌換這個小小的模式,測試電子郵件地址的方式有一個更大的模式,即78列81行,並有幾十個字符可用。 (其中我不是建議使用,或任何其他正則表達式,測試電子郵件地址。工作錯誤的工具。)如果你想嚇倒你自己,請在ex-parrot網站上看看它。我沒有任何關係!
你解析一個現有的語言,或者這是一種自定義格式? – Ryan
這是一種自定義語言 – Crimson7
[本頁可能有所幫助](http://www.rexegg.com/regex-best-trick.html#notarzan)? '「[^」] *「|(//.*)',但不包括轉義的引號 - 例如''some \」// thing「'。 –