改进RegEx搜索

时间:2013-02-20 14:26:24

标签: c# regex

使用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();
}

这是对的吗?

4 个答案:

答案 0 :(得分:1)

您现有的正则表达式:

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

匹配OU=,然后是一些字母和反斜杠([a-zA-Z\\]+),然后是逗号,然后匹配到行尾的任何字符(.*)($

因此,单个匹配将始终匹配第一个OU部分后的整行。

通过删除最后的,.*$修改您的正则表达式,它将匹配每个OU组:

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

另请注意,括号是一个捕获组。如果您还希望仅捕获值部分,它们很有用,但如果您不使用它,则它们不是必需的,您可以这样做:

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

答案 1 :(得分: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);
}

答案 2 :(得分: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"));
}

答案 3 :(得分:0)

Group[0]返回完整匹配: Group[1]返回匹配中的第一个模式[即第一个括号中的所有内容'('')']

所以,如果你想准确地获得OU的那两次出现......你可以这样做:

 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]返回匹配中的第二个模式[即第二个括号中的所有内容'('')']

,并提供: 商店 COMPANY

但我假设您不希望对您感兴趣的每个模式使用正则表达式如此明确。 如果你想获得多个匹配,那么你需要进行Regex的Matches调用,返回一个Matchcollection。

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

这仍然不适用于您当前的正则表达式,因为STORE的所有内容都会在第一场比赛中结束。如果您只想在“OU =”

之后获得“1或更多字母”模式

你只需要:

@"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 "(" ")"
}