string.IndexOf 忽略转义序列

时间:2021-05-12 09:50:44

标签: c# string indexof

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

这是说明问题的示例字符串

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

我想要的是第一个未转义的 ',' 字符的位置,即位置 32。

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

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

3 个答案:

答案 0 :(得分:1)

假设 \ 应该由本身转义:\\ 只放 \,您可以实现一个简单的 有限状态机

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, ',');

答案 1 :(得分:1)

您可以使用正则表达式:

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

它使用了否定的lookbehind,所以检查所有的逗号,看看它前面是否没有反斜杠。

答案 2 :(得分:0)

我的同事提出了这个正则表达式。不完全是问题,但由于我想要职位然后使用 SubString 它也可以解决问题。

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

我担心它会归结为正则表达式,如 Tim 的解决方案,或“蛮力”,如 Dmitry 的解决方案。

相关问题