2012-07-09 16 views
2

我正在嘗試開發內部標記語言的代碼驗證系統,但我遇到了一些麻煩我對正則表達式的經驗不足。該語言中的標籤遵循以下格式:我遇到了與我不想要的正則表達式匹配案例的問題(數據驗證)

{tag:number:phrase 1 |短語2 ... |短語n}

其中number是範圍內的數字(3.0,3.5,4.0 ... 8.5),並且恰好其中一個短語在其末尾必須帶有星號並且必須至少有兩個短語。請注意,標籤不區分大小寫,空白不重要。

我使用的正則表達式是:

\{ ?(mw) ?: ?[3-8]{1}(.0|.5)? ?((((\| ?(\w ?)+[\p{P}]? ?)*)+((\| ?(\w\ ?)+[\p{P}]?)* ?\* ?)+((\| ?(\w ?)+[\p{P}]? ?)*)?)|(((\| ?(\w ?)+[\p{P}]? ?)*)?((\| ?(\w ?)+[\p{P}]?)* ?\* ?)+((\| ?(\w ?)+[\p{P}]? ?)*)+))(?\}) 

這確實正確的情況下匹配:

{ mw : 3.5 | phrase 1 | phrase 2* | phrase 3} 

也是不正確的情況:

{ mw : 3.5 | phrase 1* | phrase 2* | phrase 3} [Two asterisks] 

{ mw : 3.5* | phrase 1 | phrase 2* | phrase 3} [An asterisk with the number value] 

感謝您的幫助。

如果有人想提供有關數據驗證系統通常工作方式的任何見解,我將不勝感激。

+0

它變得更容易處理,如果你considere三個獨立(例如@ archeong87的答案):1)短語,後面跟着帶星號的短語,2)帶星號的短語,後面跟着沒有的短語,以及3)帶星號的短語,由沒有的短語包圍。 – fork0 2012-07-09 14:50:21

+0

@ fork0 - 也可以,但實際上我所做的是:0個或更多沒有星號的短語,1個帶星號的短語和0個或更多沒有星號的短語。實際上相同,但你的措辭表明更多地使用替換,''|''。 – 2012-07-09 15:00:20

+0

這是一個要求,害怕... – fork0 2012-07-09 15:03:47

回答

0

這裏:

\{\s*(\w+)\s*:\s*([3-8]\.[05])\s*(\|[^|*\n]*)*(\|[^|*\n]*\*\s*)(\|[^|*\n]*)*\} 

這裏的a demo,用下面的輸入測試:

{ mw : 3.5 | hello, world | says | i } 
{ mw : 3.5 | hello,* world | says | i } 
{ mw : 3.5 | hello, world* | says | i } 
{ mw : 3.5 | hello, world | says* | i } 
{ mw : 3.5 | hello, world | says | i* } 
{ mw : 3.5 } 
{ mw : 3.5 | } 
{ mw : 3.5* | } 
{ mw : 3.5 | hello, world } 
{ mw : 3.5 | hello, world* } 

UPDATE

的一些注意事項。

  1. 在您原來的正則表達式中, ?表示「0或1個空格字符」。你可能意思是\s*這意味着「0或更多的空白字符」。
  2. 在您的原始正則表達式中,請注意(.0|.5)實際上匹配A0B5
  3. 您可能需要修改我的正則表達式以重新整理您在[\p{P}]?中所做的任何事情。
  4. 它看起來像你在正確的軌道上,但你可能已經過於複雜的一些東西,並且很可能是你的空白表達式混亂了你的正則表達式。我鼓勵使用我上面鏈接的工具,regexpal.com,一塊一塊地測試你的正則表達式,看看事情沒有按預期工作。

更新2

高度懷疑你能添加標記,但x標誌將大大縮短這個表達式:

\{(\w+):([3-8]\.[05])(\|[^|*\n]*)*(\|[^|*\n]*\*)(\|[^|*\n]*)*\} 
+0

我相信OP要求「\ s *」(空白無關緊要) – fork0 2012-07-09 14:52:20

+0

啊,你說得對。我不確定我在想什麼。謝謝! – 2012-07-09 14:54:19

+0

非常感謝。這簡化了很多事情,但現在我有兩個問題。正則表達式現在只匹配1個字長的短語(這是沒有意義的,因爲你使用的是我所做的\ w +標記)。 「|你好|世界* |說...」工作正常,但「|你好世界* |說...」不。還有什麼(?:意思是準確的? 但是真的這是一個很好的答案,正則表達式比我的簡潔得多 – 2012-07-09 14:58:25

1

這看起來像一個適當語法的地方,並使用解析工具(如yacc,antlr等)來構建將實際爲您解析的代碼。正則表達式只能做這麼多,但看起來可能存在DSL的不精確定義。

或者您將需要使用多個單一的正則表達式來驗證您的特殊情況,這些情況不能用單個表達式找到。

+0

我會同意,如果我們在談論HTML或其他涉及遞歸嵌套組的問題,但是這個問題沒有遞歸,並且很容易通過正則表達式來處理。 「'|''不是像''()'',''[''''和'{}''這樣的可嵌套括號內的短語分隔符。 – 2012-07-09 15:22:54