【问题标题】:C# Extracting a name from a stringC#从字符串中提取名称
【发布时间】:2008-12-10 15:31:22
【问题描述】:

我想从下面的字符串中提取“James\, Brown”,但我并不总是知道名字是什么。逗号让我有些困惑,那么你建议如何提取 James\,Brown?

OU=James\, Brown,OU=Test,DC=Internal,DC=Net

谢谢

【问题讨论】:

  • 太糟糕了,您无法获得用于以结构化格式提供输出的 API。解析很烦人。

标签: c# regex string


【解决方案1】:

正则表达式可能是您最好的方法

static string ParseName(string arg) {
    var regex = new Regex(@"^OU=([a-zA-Z\\]+\,\s+[a-zA-Z\\]+)\,.*$");
    var match = regex.Match(arg);
    return match.Groups[1].Value;
}

【讨论】:

  • 一个很好的方法,但其中一个我有一种非理性的恐惧。 :)
  • 但为了做到这一点,我必须承认我的恐惧是错误的,作为约克郡人,我从来没有错。 ;-)
  • 您假设每个名称中都有一个逗号,这可能是错误的(并且可能是)。
  • @David,提问者没有以任何方式提及它,所以我只能继续他们在问题中提出的内容。我还想知道名称中是否允许使用@。或者可能是 3 名与 2 名。但除非提问者在他们的问题中提出,否则再次假设是必要的。
  • @Jared:我只是指出 2 年后生产代码中可能出现的潜在错误 ;-)。仍然提供的示例看起来真的很像 LDAP DN,这就是为什么我更喜欢 Mark Brackett 的答案。
【解决方案2】:

您可以使用正则表达式:

string input = @"OU=James\, Brown,OU=Test,DC=Internal,DC=Net";
Match m = Regex.Match(input, "^OU=(.*?),OU=.*$");
Console.WriteLine(m.Groups[1].Value);   

【讨论】:

    【解决方案3】:

    一个非常脆弱的方法可能是......

    string name = @"OU=James\, Brown,OU=Test,DC=Internal,DC=Net";
    string[] splitUp = name.Split("=".ToCharArray(),3);
    string namePart = splitUp[1].Replace(",OU","");
    Console.WriteLine(namePart);
    

    我不一定会提倡这种方法,但我刚从部门圣诞午餐回来,我的大脑还没有完全投入。

    【讨论】:

    • 嗨,我叫“Foo,OUBar”,但你可以叫我“FooBar” ;-)
    【解决方案4】:

    我会从一个正则表达式开始拆分组:

        Regex rx = new Regex(@"(?<!\\),");
        String test = "OU=James\\, Brown,OU=Test,DC=Internal,DC=Net";
        String[] segments = rx.Split(test);
    

    但是从那里我将通过手动拆分数组中的参数来拆分它们,这样您就不必使用依赖于所用分隔符以外的正则表达式。由于这看起来像一个 LDAP 查询,因此您是否总是查看 params[0] 可能无关紧要,但有可能将名称设置为“CN=”。您可以通过阅读这样的查询来涵盖这两种情况:

        String name = segments[0].Split('=', 2)[1];
    

    【讨论】:

      【解决方案5】:

      这看起来很像根据RFC 2253/4514 格式化的 LDAP 或 Active Directory 专有名称。

      除非您使用的是众所周知的名称和/或可以接受脆弱的黑客攻击(例如正则表达式解决方案),否则您应该从阅读规范开始。

      如果您像我一样通常讨厌根据 RFC 实现代码 - 那么希望 this guy 在遵循规范方面做得比您做得更好。至少他声称符合 2253。

      【讨论】:

        【解决方案6】:

        如果斜线始终存在,我会考虑使用 RegEx 进行匹配,您可以使用匹配组来表示姓氏和名字。

        ^OU=([a-zA-Z])\,\s([a-zA-Z])

        RegEx 将匹配仅包含字符的名称,您需要对其进行一些改进以便更好地匹配非标准名称。如果你走这条路,Here is a RegEx tester 会一路帮助你。

        【讨论】:

          【解决方案7】:

          用您自己喜欢的魔法字符串(可能是 & #44;)替换 \,拆分剩余的逗号或搜索到第一个逗号,然后用单个逗号替换您的魔法字符串。

          即比如:

          string originalStr = @"OU=James\, Brown,OU=Test,DC=Internal,DC=Net";
          string replacedStr = originalStr.Replace("\,", "&#44;");
          
          string name = replacedStr.Substring(0, replacedStr.IndexOf(","));
          Console.WriteLine(name.Replace("&#44;", ","));
          

          【讨论】:

            【解决方案8】:

            假设您在 Windows 中运行,请将 PInvoke 与 DsUnquoteRdnValueW 结合使用。代码见我对另一个问题的回答:https://stackoverflow.com/a/11091804/628981

            【讨论】:

              【解决方案9】:

              如果格式始终相同:

              string line = GetStringFromWherever();
              
              int start = line.IndexOf("=") + 1;//+1 to get start of name
              int end = line.IndexOf("OU=",start) -1; //-1 to remove comma
              
              string name = line.Substring(start, end - start);
              

              如果语法不完全正确,请原谅 - 凭记忆。显然,这不是很健壮,如果格式发生变化,它就会失败。

              【讨论】:

              • 其实SubString的第二个参数是length,而不是endIndex。在您的示例中,它应该是 name = line.SubString(start, end - start)。我一直讨厌 Substring,这就是我创建允许 startIndex 和 endIndex 的扩展方法的原因。
              • xan - 我编辑了正确的语法,因为我在安装了 Snippetcompiler 的机器前。 :)
              猜你喜欢
              • 2013-06-18
              • 1970-01-01
              • 1970-01-01
              • 2022-08-12
              • 1970-01-01
              • 2019-08-22
              • 2015-05-12
              • 2021-09-03
              • 1970-01-01
              相关资源
              最近更新 更多