开发者

String-parsing-fu: Can you help me find a way to retrieve this value?

开发者 https://www.devze.com 2023-02-18 08:45 出处:网络
I need to somehow detect if there is a parent OU value, and if there is retrieve it. For example, here there is no parent:

I need to somehow detect if there is a parent OU value, and if there is retrieve it.

For example, here there is no parent:

LDAP://servera/OU=Santa Cruz,DC=contoso,DC=com

But here, there is a parent:

LDAP://servera/OU=Ventas,OU=Santa Cruz,DC=contoso,DC=c开发者_Go百科om

So I would need to retrieve that "Ventas" string.

Another example:

LDAP://servera/OU=Contabilidad,OU=Ventas,OU=Santa Cruz,DC=contoso,DC=com

I would need to retrieve that "Ventas" string as well.

Any suggestions on how to tackle this?


string ldap = "LDAP://servera/OU=Ventas,OU=Santa Cruz,DC=contoso,DC=com";
Match match = Regex.Match(ldap, @"LDAP://\w+/OU=(?<toplevelou>\w+?),OU=");
if(match.Success)
{
    Console.WriteLine(match.Result("${toplevelou}"));
}


I'd find the first occurrence of OU=... and get it's value. Then I'd check if there was another occurrence after it. If so, return the value I've got. If not, return whatever it is you want if there's no parent (String.Empty, or, null, or whatever).

You could also use a regular express like this:

var regex = new Regex(@"OU=(.*?),");
var matches = regex.Matches(ldapString);

Then check how many matches there are. If >1 return the captured value from the first match.

Update

The regex above needs to be improved to allow the case where there's an escaped comma (\,) in the LDAP string. Maybe something like:

var regex = new Regex(@"OU=((.*?(\\\,)+?)+?),");

That may be broken, and there may be simpler way to do the same thing. I'm not a regex wizard.

Another Update

Per Kimberly's comment below the regex should be @"OU=((?:.*?(?:\\\,)*?)+?),".


Call me crazy, but I 'd do it this way (hey ma, look, an one-liner!):

var str = "LDAP://servera/OU=Ventas,OU=Santa Cruz,DC=contoso,DC=com";
var result = str.Substring(str.LastIndexOf('/') + 1).Split(',')
                .Select(s => s.Split('='))
                .Where(a => a[0] == "OU")
                .Select(a => a[1])
                .Reverse().Skip(1).FirstOrDefault();

result is either null or has the string you want. This will work no matter how many OUs are in there and return the second-to-last one, as long as the format of the string is valid to begin with.

Update: possible improvements:

The above will not work correctly if your DN contains an escaped forward slash or an escaped comma.

To fix both of these you need to use regular expressions. Change:

str.Substring(str.LastIndexOf('/') + 1).Split(',')

to:

Regex.Split(Regex.Split(str, "(?<!\\\\)/").Last(), "(?<!\\\\),")

What this does is separate the DN by getting the last part of str after splitting on forward slashes, and split the in parts DN by splitting on commas. In both cases, negative lookbehind is used to make sure that the slashes/commas are not escaped.

Not as pretty, I know. But it's still an one-liner (yay!) and it still allows you to use LINQ further down to handle multiple OUs any way you choose to.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号