2012-08-03 87 views
0

我有一個特殊的要求,我的正則表達式模式將在運行時確定,比如說我有一個日期,並希望它被檢查對mm-dd-yyyymm/dd/yyyyd.mm.yyyy東西基本上我會餵食模式爲NN-NN-TTTT其中N表示一個數字,T表示一個字母,表達式可以是任何東西。我們可以編寫任何適合這種需求的正則表達式嗎?正則表達式查詢(運行時可定製)

我的形式看起來就像是顯示在http://jsfiddle.net/E2EHZ/數據將匹配對應的文本框中

T指定模式 - 信
N - 數字
A - Alphanum

+0

你能提供一些具體的例子嗎? – 2012-08-03 07:00:12

+1

正如我所見,'T'也是數字,不是嗎? 無論如何,純粹用正則表達式完成的日期驗證是不可靠的,至少可以說。 – 2012-08-03 07:07:49

+0

已更新的問題 – Varun 2012-08-03 07:09:47

回答

3

所以基本上你將有您的用戶輸入的模式包含T,NA作爲佔位符與其他字符需要匹配字面之間?如果是這樣,那麼它很容易:只需用適當的字符類替換佔位符,引用其餘的(所以正則表達式元字符被轉義)並將結果用作正則表達式。

第一次逃逸即不是A,NT。如何做到這一點因語言而異,但基本上你會用比賽的轉義版本代替[^ANT]+。在C#中它可能是這樣的:

Regex.Replace(s, "[^ANT]+", m => Regex.Escape(m.Value)); 

或Java中:

s.replaceAll("[^ANT]+", "\\Q$0\\E" 

的翻譯來執行,然後很簡單:

T → [a-zA-Z] 
N → [0-9] 
A → [0-9a-zA-Z] 

也就是說,假設ASCII只。對於Unicode您可能需要

T → \p{L} 
N → \p{Nd} 
A → [\p{L}\p{Nd}] 

改爲。另請注意,如果您執行簡單的字符串替換,則需要首先用ASCII版本替換A,首先替換爲Unicode變體的N,以避免在後續結果中替換它。

最後,如果要匹配完整字符串,最後可能需要在字符串前加上^並將其後綴爲$

在C#示例實現(有一個微小的優化):

string CreateRegex(string pattern) { 
    string result = Regex.Replace(pattern, "[^ANT]+", m => Regex.Escape(m.Value)); 
    result = Regex.Replace(result, "A+", m => "[0-9a-zA-Z]" + (m.Length > 1 ? "{"+m.Length+"}" : "")); 
    result = Regex.Replace(result, "T+", m => "[a-zA-Z]" + (m.Length > 1 ? "{"+m.Length+"}" : "")); 
    result = Regex.Replace(result, "N+", m => "[0-9]" + (m.Length > 1 ? "{"+m.Length+"}" : "")); 
    return "^" + result + "$"; 
} 

這對於在下面的示例結果:

NN-NN-TTTT → ^[0-9]{2}-[0-9]{2}-[a-zA-Z]{4}$ 
*(@&#^(&%(@ AA-AA-NN-TTTTTTTT lreglig → \*\(@&\#\^\(&%\(@\ \ [0-9a-zA-Z]{2}-[0-9a-zA-Z]{2}-[0-9]{2}-[a-zA-Z]{8}\ lreglig 

或者在Java中(不說的優化,因爲我想不通如何使用一個功能作爲替換):

String createRegex(String pattern) { 
    String result = pattern.replaceAll("[^ANT]+", "\\Q$0\\E"); 
    result = result.replaceAll("A", "[0-9a-zA-Z]"); 
    result = result.replaceAll("T", "[a-zA-Z]"); 
    result = result.replaceAll("N", "[0-9]"); 
    return "^" + result + "$"; 
} 

由此產生的正則表達式將是一個因爲上面的代碼不會對相同的令牌使用重複。

+0

是的,它會的。你需要稍微修改實際的代碼,但基本的想法是一樣的。 – Joey 2012-08-03 08:49:03

+0

答案是什麼'string result = Regex.Replace(s,「[^ ANT] +」,m => Regex.Escape(m.Value));' – Varun 2012-08-03 08:54:45

+0

請參閱編輯。 Java代碼未經測試,但可能有效。但正如我所說,總的想法是一樣的;它在語法上看起來略有不同;) – Joey 2012-08-03 08:59:16