字符串.IndexOf忽略转义序列



我正在尝试提取LDAP DN字符串的CN。

下面是一个示例字符串,说明问题

var dn = @"CN=Firstname Lastname, Organization,OU=some ou,DC=company,DC=com";

我想要的是第一个未转义的","字符的位置,它位于位置32。

var pos = dn.IndexOf(',');

返回第一个逗号,无论是否转义。现在,我可以使用IndexOf跳过字符串中的转义逗号吗?

假设应该由本身转义\只放,则可以实现有限状态机

private static int IndexOfUnescaped(string source, 
char toFind, 
char escapement = '\') {
if (string.IsNullOrEmpty(source))
return -1;
for (int i = 0; i < source.Length; ++i) 
if (source[i] == escapement)
i += 1; // <- skip the next (escaped) character
else if (source[i] == toFind)
return i;
return -1;
}
...
var dn = @"CN=Firstname Lastname, Organization,OU=some ou,DC=company,DC=com";
var pos = IndexOfUnescaped(dn, ',');

您可以使用Regex:

string s = @"CN=Firstname Lastname, Organization,OU=some ou,DC=company,DC=com";
Regex regex = new Regex("(?<!\\),", RegexOptions.Compiled);
int firstMatch = regex.Matches(s).FirstOrDefault()?.Index ?? -1;

演示:https://regex101.com/r/Jxco8K/1

它使用了一个负的lookbacking,所以检查所有的逗号,看看它前面是否没有反斜杠。

我的同事想出了这个正则表达式。这不完全是个问题,但由于我想让这个职位使用SubString,它也起到了作用。

var CnRegex = new Regex(@"([a-zA-Z_]*)=((?:[^\,}]|\.)*)");
var match = CnRegex.Match(input);
if (match.Success)
return match.Value;
return null;

我担心这会像蒂姆的解决方案那样归结为Regex,或者像德米特里的解决方案一样归结为"蛮力"。

最新更新