2013-03-22 71 views
38

假设我有这样的字符串:如何计算子字符串的出现次数?

MyString = "OU=Level3,OU=Level2,OU=Level1,DC=domain,DC=com"; 

那么我想知道的子字符串“OU =”此字符串中出现的多少时间。随着单个字符,也许是这样的:

int count = MyString.Split("OU=").Length - 1; 

Split仅适用于char,不string

另外如何找到n次出现的位置?例如,第二个"OU="在字符串中的位置?

如何解决此问题?

+1

'String.Split'有几个重载,允许您按字符串拆分。请参阅http://msdn.microsoft.com/en-us/library/tabh47cf.aspx – shf301 2013-03-22 18:37:31

+0

拆分不适用于chars ... – MUG4N 2013-03-22 18:43:53

+0

您可以使用Multiple Delim完成此操作我将非常乐意发布您简单的编码示例供将来使用。 '和Split可以在字符串上工作''请记住Split()返回一个数组,所以在字符串的情况下它会返回字符串[],您需要创建新的字符串[] {“somestring”,“someotherString”.. etc ..}' – MethodMan 2013-03-22 18:51:19

回答

96
Regex.Matches(input, "OU=").Count 
+0

谢谢。另外如何找到n个发生的位置?例如,字符串中的第二个时间“OU =”的位置? – KentZhou 2013-03-22 18:38:52

+0

戳了一下,发现了这个问题,这应该可以帮助你:http://stackoverflow.com/questions/767767/finding-multiple-indexes-from-source-string – tnw 2013-03-22 18:42:44

+0

@KentZhou你会介意接受我的答案,如果这是你的问题的解决方案? – tnw 2013-03-22 18:46:54

2
int count = myString.Split(new []{','}) 
        .Count(item => item.StartsWith(
         "OU=", StringComparison.OrdinalIgnoreCase)) 
下面
+1

不要嘟my我自己的号角,但这依赖于逗号分隔。当然,它适用于这个特定的场景,但是我的Regex解决方案更简单,更具动态性。 – tnw 2013-03-22 18:38:24

+0

是的,我同意,只是给出一个替代方案。 – Phil 2013-03-22 18:39:19

+0

当然,我可以理解这一点。+1 – tnw 2013-03-22 18:48:08

2

应该工作

MyString = "OU=Level3,OU=Level2,OU=Level1,DC=domain,DC=com"; 
    int count = Regex.Matches(MyString, "OU=").Count 
10

你可以找到所有的事件和他们的立场与IndexOf

string MyString = "OU=Level3,OU=Level2,OU=Level1,DC=domain,DC=com"; 
string stringToFind = "OU="; 

List<int> positions = new List<int>(); 
int pos = 0; 
while ((pos < MyString.Length) && (pos = MyString.IndexOf(stringToFind, pos)) != -1) 
{ 
    positions.Add(pos); 
    pos += stringToFind.Length(); 
} 

Console.WriteLine("{0} occurrences", positions.Count); 
foreach (var p in positions) 
{ 
    Console.WriteLine(p); 
} 

你可以从正则表达式相同的结果:

var matches = Regex.Matches(MyString, "OU="); 
Console.WriteLine("{0} occurrences", matches.Count); 
foreach (var m in matches) 
{ 
    Console.WriteLine(m.Index); 
} 

的主要区别:

  • 正则表达式的代码越短
  • 正则表达式的代码分配的集合和多个字符串。
  • 可以写入IndexOf代码以立即输出位置,而无需创建集合。
  • 很可能正则表达式代码的隔离速度会更快,但如果多次使用字符串分配的组合开销可能会导致垃圾收集器的负载高得多。

如果我正在写这个内联,作为一些没有经常使用的东西,我可能会使用正则表达式解决方案。如果我把它放到一个图书馆当中,那么我可能会使用IndexOf解决方案。

+0

+1不错的写法 – tnw 2013-03-22 19:05:52

+1

小字谜?列表职位=新列表 [];应该是列表职位=新列表(); – RickL 2017-02-15 13:53:31

+0

我相信这是一个更好的解决方案。如果你试图匹配的字符串是.s那么正则表达式将返回不正确的数字。 Jim提出的while循环正确计数.s的数量。 – ashlar64 2017-05-23 15:55:36

5

(大眼夹模式:ON

你看起来就像你解析LDAP查询!

你想对它进行解析:

  • 手动?转到“拆分和分页”
  • 通过Win32调用自动创建?转到

“通过PInvoke的使用的Win32”(大眼夹模式:OFF

“SplittingAndParsing”:

var MyString = "OU=Level3,OU=Level2,OU=Level1,DC=domain,DC=com"; 
var chunksAsKvps = MyString 
    .Split(',') 
    .Select(chunk => 
     { 
      var bits = chunk.Split('='); 
      return new KeyValuePair<string,string>(bits[0], bits[1]); 
     }); 

var allOUs = chunksAsKvps 
    .Where(kvp => kvp.Key.Equals("OU", StringComparison.OrdinalIgnoreCase)); 

“通过PInvoke的使用的Win32”:

用法:

var parsedDn = Win32LDAP.ParseDN(str);  
var allOUs2 = parsedDn 
    .Where(dn => dn.Key.Equals("OU", StringComparison.OrdinalIgnoreCase)); 

实用代码:

// I don't remember where I got this from, honestly...I *think* it came 
// from another SO user long ago, but those details I've lost to history... 
public class Win32LDAP 
{ 
    #region Constants 
    public const int ERROR_SUCCESS = 0; 
    public const int ERROR_BUFFER_OVERFLOW = 111; 
    #endregion Constants 

    #region DN Parsing 
    [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)] 
    protected static extern int DsGetRdnW(
     ref IntPtr ppDN, 
     ref int pcDN, 
     out IntPtr ppKey, 
     out int pcKey, 
     out IntPtr ppVal, 
     out int pcVal 
    ); 

    public static KeyValuePair<string, string> GetName(string distinguishedName) 
    { 
     IntPtr pDistinguishedName = Marshal.StringToHGlobalUni(distinguishedName); 
     try 
     { 
      IntPtr pDN = pDistinguishedName, pKey, pVal; 
      int cDN = distinguishedName.Length, cKey, cVal; 

      int lastError = DsGetRdnW(ref pDN, ref cDN, out pKey, out cKey, out pVal, out cVal); 

      if(lastError == ERROR_SUCCESS) 
      { 
       string key, value; 

       if(cKey < 1) 
       { 
        key = string.Empty; 
       } 
       else 
       { 
        key = Marshal.PtrToStringUni(pKey, cKey); 
       } 

       if(cVal < 1) 
       { 
        value = string.Empty; 
       } 
       else 
       { 
        value = Marshal.PtrToStringUni(pVal, cVal); 
       } 

       return new KeyValuePair<string, string>(key, value); 
      } 
      else 
      { 
       throw new Win32Exception(lastError); 
      } 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(pDistinguishedName); 
     } 
    } 

    public static IEnumerable<KeyValuePair<string, string>> ParseDN(string distinguishedName) 
    { 
     List<KeyValuePair<string, string>> components = new List<KeyValuePair<string, string>>(); 
     IntPtr pDistinguishedName = Marshal.StringToHGlobalUni(distinguishedName); 
     try 
     { 
      IntPtr pDN = pDistinguishedName, pKey, pVal; 
      int cDN = distinguishedName.Length, cKey, cVal; 

      do 
      { 
       int lastError = DsGetRdnW(ref pDN, ref cDN, out pKey, out cKey, out pVal, out cVal); 

       if(lastError == ERROR_SUCCESS) 
       { 
        string key, value; 

        if(cKey < 0) 
        { 
         key = null; 
        } 
        else if(cKey == 0) 
        { 
         key = string.Empty; 
        } 
        else 
        { 
         key = Marshal.PtrToStringUni(pKey, cKey); 
        } 

        if(cVal < 0) 
        { 
         value = null; 
        } 
        else if(cVal == 0) 
        { 
         value = string.Empty; 
        } 
        else 
        { 
         value = Marshal.PtrToStringUni(pVal, cVal); 
        } 

        components.Add(new KeyValuePair<string, string>(key, value)); 

        pDN = (IntPtr)(pDN.ToInt64() + UnicodeEncoding.CharSize); //skip over comma 
        cDN--; 
       } 
       else 
       { 
        throw new Win32Exception(lastError); 
       } 
      } while(cDN > 0); 

      return components; 
     } 
     finally 
     { 
      Marshal.FreeHGlobal(pDistinguishedName); 
     } 
    } 

    [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)] 
    protected static extern int DsQuoteRdnValueW(
     int cUnquotedRdnValueLength, 
     string psUnquotedRdnValue, 
     ref int pcQuotedRdnValueLength, 
     IntPtr psQuotedRdnValue 
    ); 

    public static string QuoteRDN(string rdn) 
    { 
     if (rdn == null) return null; 

     int initialLength = rdn.Length; 
     int quotedLength = 0; 
     IntPtr pQuotedRDN = IntPtr.Zero; 

     int lastError = DsQuoteRdnValueW(initialLength, rdn, ref quotedLength, pQuotedRDN); 

     switch (lastError) 
     { 
      case ERROR_SUCCESS: 
       { 
        return string.Empty; 
       } 
      case ERROR_BUFFER_OVERFLOW: 
       { 
        break; //continue 
       } 
      default: 
       { 
        throw new Win32Exception(lastError); 
       } 
     } 

     pQuotedRDN = Marshal.AllocHGlobal(quotedLength * UnicodeEncoding.CharSize); 

     try 
     { 
      lastError = DsQuoteRdnValueW(initialLength, rdn, ref quotedLength, pQuotedRDN); 

      switch(lastError) 
      { 
       case ERROR_SUCCESS: 
        { 
         return Marshal.PtrToStringUni(pQuotedRDN, quotedLength); 
        } 
       default: 
        { 
         throw new Win32Exception(lastError); 
        } 
      } 
     } 
     finally 
     { 
      if(pQuotedRDN != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(pQuotedRDN); 
      } 
     } 
    } 


    [DllImport("ntdsapi.dll", CharSet = CharSet.Unicode)] 
    protected static extern int DsUnquoteRdnValueW(
     int cQuotedRdnValueLength, 
     string psQuotedRdnValue, 
     ref int pcUnquotedRdnValueLength, 
     IntPtr psUnquotedRdnValue 
    ); 

    public static string UnquoteRDN(string rdn) 
    { 
     if (rdn == null) return null; 

     int initialLength = rdn.Length; 
     int unquotedLength = 0; 
     IntPtr pUnquotedRDN = IntPtr.Zero; 

     int lastError = DsUnquoteRdnValueW(initialLength, rdn, ref unquotedLength, pUnquotedRDN); 

     switch (lastError) 
     { 
      case ERROR_SUCCESS: 
       { 
        return string.Empty; 
       } 
      case ERROR_BUFFER_OVERFLOW: 
       { 
        break; //continue 
       } 
      default: 
       { 
        throw new Win32Exception(lastError); 
       } 
     } 

     pUnquotedRDN = Marshal.AllocHGlobal(unquotedLength * UnicodeEncoding.CharSize); 

     try 
     { 
      lastError = DsUnquoteRdnValueW(initialLength, rdn, ref unquotedLength, pUnquotedRDN); 

      switch(lastError) 
      { 
       case ERROR_SUCCESS: 
        { 
         return Marshal.PtrToStringUni(pUnquotedRDN, unquotedLength); 
        } 
       default: 
        { 
         throw new Win32Exception(lastError); 
        } 
      } 
     } 
     finally 
     { 
      if(pUnquotedRDN != IntPtr.Zero) 
      { 
       Marshal.FreeHGlobal(pUnquotedRDN); 
      } 
     } 
    } 
    #endregion DN Parsing 
} 

public class DNComponent 
{ 
    public string Type { get; protected set; } 
    public string EscapedValue { get; protected set; } 
    public string UnescapedValue { get; protected set; } 
    public string WholeComponent { get; protected set; } 

    public DNComponent(string component, bool isEscaped) 
    { 
     string[] tokens = component.Split(new char[] { '=' }, 2); 
     setup(tokens[0], tokens[1], isEscaped); 
    } 

    public DNComponent(string key, string value, bool isEscaped) 
    { 
     setup(key, value, isEscaped); 
    } 

    private void setup(string key, string value, bool isEscaped) 
    { 
     Type = key; 

     if(isEscaped) 
     { 
      EscapedValue = value; 
      UnescapedValue = Win32LDAP.UnquoteRDN(value); 
     } 
     else 
     { 
      EscapedValue = Win32LDAP.QuoteRDN(value); 
      UnescapedValue = value; 
     } 

     WholeComponent = Type + "=" + EscapedValue; 
    } 

    public override bool Equals(object obj) 
    { 
     if (obj is DNComponent) 
     { 
      DNComponent dnObj = (DNComponent)obj; 
      return dnObj.WholeComponent.Equals(this.WholeComponent, StringComparison.CurrentCultureIgnoreCase); 
     } 
     return base.Equals(obj); 
    } 

    public override int GetHashCode() 
    { 
     return WholeComponent.GetHashCode(); 
    } 
} 

public class DistinguishedName 
{ 
    public DNComponent[] Components 
    { 
     get 
     { 
      return components.ToArray(); 
     } 
    } 

    private List<DNComponent> components; 
    private string cachedDN; 

    public DistinguishedName(string distinguishedName) 
    { 
     cachedDN = distinguishedName; 
     components = new List<DNComponent>(); 
     foreach (KeyValuePair<string, string> kvp in Win32LDAP.ParseDN(distinguishedName)) 
     { 
      components.Add(new DNComponent(kvp.Key, kvp.Value, true)); 
     } 
    } 

    public DistinguishedName(IEnumerable<DNComponent> dnComponents) 
    { 
     components = new List<DNComponent>(dnComponents); 
     cachedDN = GetWholePath(","); 
    } 

    public bool Contains(DNComponent dnComponent) 
    { 
     return components.Contains(dnComponent); 
    } 

    public string GetDNSDomainName() 
    { 
     List<string> dcs = new List<string>(); 
     foreach (DNComponent dnc in components) 
     { 
      if(dnc.Type.Equals("DC", StringComparison.CurrentCultureIgnoreCase)) 
      { 
       dcs.Add(dnc.UnescapedValue); 
      } 
     } 
     return string.Join(".", dcs.ToArray()); 
    } 

    public string GetDomainDN() 
    { 
     List<string> dcs = new List<string>(); 
     foreach (DNComponent dnc in components) 
     { 
      if(dnc.Type.Equals("DC", StringComparison.CurrentCultureIgnoreCase)) 
      { 
       dcs.Add(dnc.WholeComponent); 
      } 
     } 
     return string.Join(",", dcs.ToArray()); 
    } 

    public string GetWholePath() 
    { 
     return GetWholePath(","); 
    } 

    public string GetWholePath(string separator) 
    { 
     List<string> parts = new List<string>(); 
     foreach (DNComponent component in components) 
     { 
      parts.Add(component.WholeComponent); 
     } 
     return string.Join(separator, parts.ToArray()); 
    } 

    public DistinguishedName GetParent() 
    { 
     if(components.Count == 1) 
     { 
      return null; 
     } 
     List<DNComponent> tempList = new List<DNComponent>(components); 
     tempList.RemoveAt(0); 
     return new DistinguishedName(tempList); 
    } 

    public override bool Equals(object obj) 
    { 
     if(obj is DistinguishedName) 
     { 
      DistinguishedName objDN = (DistinguishedName)obj; 
      if (this.Components.Length == objDN.Components.Length) 
      { 
       for (int i = 0; i < this.Components.Length; i++) 
       { 
        if (!this.Components[i].Equals(objDN.Components[i])) 
        { 
         return false; 
        } 
       } 
       return true; 
      } 
      return false; 
     } 
     return base.Equals(obj); 
    } 

    public override int GetHashCode() 
    { 
     return cachedDN.GetHashCode(); 
    } 
} 
1

这里有一个如何得到你正在寻找

var MyString = "OU=Level3,OU=Level2,OU=Level1,DC=domain,DC=com"; 

这一个结果,你会看到分开的值的列表中有两个例子,但它会有DC只是一个想法 表明,与字符串的分割确实工作'

var split = MyString.Split(new string[] { "OU=", "," }, StringSplitOptions.RemoveEmptyEntries); 

这一次会分裂,并返回只有3项为一个列表,这样,如果你不依赖于一个数,您可以直观地验证它返回的`OU =``

var lstSplit = MyString.Split(new[] { ',' }) 
     .Where(splitItem => splitItem.StartsWith(
       "OU=", StringComparison.OrdinalIgnoreCase)).ToList(); 
3

一个3级这个扩展需要比常规表达式更少的资源。

public static int CountSubstring(this string text, string value) 
{     
    int count = 0, minIndex = text.IndexOf(value, 0); 
    while (minIndex != -1) 
    { 
     minIndex = text.IndexOf(value, minIndex + value.Length); 
     count++; 
    } 
    return count; 
} 

用法:

MyString = "OU=Level3,OU=Level2,OU=Level1,DC=domain,DC=com"; 
int count = MyString.CountSubstring("OU="); 
0
public static int CountOccurences(string needle, string haystack) 
{ 
    return (haystack.Length - haystack.Replace(needle, "").Length)/needle.Length; 
} 

基准它与其他的答案在这里(正则表达式一个和 “的IndexOf” 之一),工作速度更快。

+0

这只是一个副本http://stackoverflow.com/questions/541954/how-would-you-count-occurrences-of-a-string-within-a-string添加至少一个参考 – fubo 2015-05-20 08:24:35

相关问题