2013-02-20 237 views
1

使用DirectoryServices.AccountManagement我得到用戶DistinguishedName它看起來像這樣:提高正則表達式搜索

CN=Adam West,OU=STORE,OU=COMPANY,DC=mycompany,DC=group,DC=eu 

我需要從這個獲得第一OU值。
我發現類似的解決方案:C# Extracting a name from a string

而且使用了一些調整我創造了這個代碼:

string input = @"CN=Adam West,OU=STORE,OU=COMPANY,DC=mycompany,DC=group,DC=eu"; 
Match m = Regex.Match(input, @"OU=([a-zA-Z\\]+)\,.*$"); 
Console.WriteLine(m.Groups[1].Value); 

此代碼返回STORE如預期,但如果我改變Groups[1]Groups[0]我得到幾乎相同的結果,輸入字符串:

OU=STORE,OU=COMPANY,DC=mycompany,DC=group,DC=eu 

如何更改此正則表達式,使其僅返回OU的值?所以在這個例子中,我得到了2個匹配的數組。如果我的字符串中有更多的OU,那麼數組會更長。

編輯: 我已經轉換我的代碼(使用@dasblinkenlight建議)進入功能:

private static List<string> GetOUs() 
{ 
    var input = @"CN=Adam West,OU=STORE,OU=COMPANY,DC=mycompany,DC=group,DC=eu"; 
    var mm = Regex.Matches(input, @"OU=([a-zA-Z\\]+)"); 
    return (from Match m in mm select m.Groups[1].Value).ToList(); 
} 

是正確的嗎?

回答

1

你的正則表達式很好(幾乎),你只是使用了錯誤的API。

刪除匹配到結束錨$的正則表達式的部分,改變Match呼籲的Matches呼叫,並獲得比賽的一環,這樣的:

var input = @"CN=Adam West,OU=STORE,OU=COMPANY,DC=mycompany,DC=group,DC=eu"; 
var mm = Regex.Matches(input, @"OU=([a-zA-Z\\]+)"); 
foreach (Match m in mm) 
    Console.WriteLine(m.Groups[1].Value); 
} 
+0

我更新了我的問題,並將我的代碼轉換爲函數。你可以看看嗎? – Misiu 2013-02-20 14:49:06

+0

@Misiu是的,改變是正確的。你可以減少'res'變量,並返回你賦給它的表達式,就像這樣:'return(from m in mm select m.Groups [1] .Value).ToList();' – dasblinkenlight 2013-02-20 14:53:57

+0

謝謝! :)是否有可能只獲得'OU'simper的第一個值?現在我得到所有OU組並且必須執行'[0]',但是也許我可以更快更輕鬆地獲得第一個OU? – Misiu 2013-02-20 15:01:48

1

您現有的正則表達式:

@"OU=([a-zA-Z\\]+)\,.*$" 

匹配OU=,然後一些字母和反斜槓([a-zA-Z\\]+),然後一個逗號,那麼任何字符(.*)到線($)結束。

因此,單個匹配將始終匹配第一個OU部分之後的整行。

通過在年底卸下,.*$修改您正則表達式,它會每個OU小組賽:

@"OU=([a-zA-Z\\]+)" 

另外還要注意,括號是捕獲組。他們是有用的,如果你也想自己捕捉只是價值的一部分,但如果你沒有使用,他們是沒有必要的,而且你可以有這樣的:

@"OU=[a-zA-Z\\]+" 
+0

如果我做'Regex.Match(input,@「OU =([a-zA-Z \\] +)」);'然後選擇組[0]我得到'OU = STORE'而不是'STORE' – Misiu 2013-02-20 14:34:36

0

這是怎麼一回事,因爲你是混合了比賽和組

string input = @"CN=Adam West,OU=STORE,OU=COMPANY,DC=mycompany,DC=group,DC=eu"; 
MatchCollection mc = Regex.Matches(input, @"OU=([a-zA-Z\\]+),"); 

foreach(Match m in mc) 
{ 
    Console.WriteLine(m.Result("$1")); 
} 
0

Group[0]返回完整匹配: Group[1]返回匹配中的第一個Pattern [ie一切都在第一個括號「(」「)」]

所以,如果你想獲得準確OU的那些2個occurances ..你可以這樣做:

Match m = Regex.Match(input, @"OU=([a-zA-Z\\]+)\,OU=([a-zA-Z\\]+)\,.*$"); 
Console.WriteLine(m.Groups[1].Value); 
Console.WriteLine(m.Groups[2].Value); 

Group[0]返回完整的匹配:(其你不想要) Group[1]返回匹配中的第一個Pattern [即第一個括號內的所有內容('')'] Group[2]返回匹配中的第二個Pattern [ie一切都在第二個括號「(」「)」]

,並提供: STORE 公司

但我假設你沒有想得那麼明確的用正則表達式的每個模式您有興趣 如果您想獲得多個匹配,那麼您需要執行返回Matchcollection的Regex的Matches調用。

MatchCollection ms = Regex.Matches(...); 

這仍然不會與當前的正則表達式的工作,雖然,因爲一切從STORE太行年底將在第一場比賽。如果你只是想後拿到模式「1或者更多字母」 a「OU =」

你只需要:

@"OU=([a-zA-Z\\]+)" 

所以,你的代碼是:

string input = @"CN=Adam West,OU=STORE,OU=COMPANY,DC=mycompany,DC=group,DC=eu"; 
MatchCollection ms = Regex.Matches(input, @"OU=([a-zA-Z\\]+)"); 

foreach (Match m in ms) 
{ 
    Console.WriteLine(m.Groups[1].Value);// get the string in the first "(" ")" 
}