【问题标题】:How to split a string while ignoring the case of the delimiter?如何在忽略分隔符的情况下拆分字符串?
【发布时间】:2009-09-16 23:51:26
【问题描述】:

我需要拆分一个字符串,假设“asdf aA asdfget aa uoiu AA”使用“aa”拆分,忽略大小写。 到

"asdf "
"asdfget "
"uoiu "

【问题讨论】:

  • Plus1 不使用真实单词但仍保持问题的连续性

标签: c# .net string


【解决方案1】:

使用string.Split 来实现这一点并不容易。 (好吧,除了为数组中的每个小写/大写字符指定拆分字符串的所有排列 - 我想你会同意的,这不是很优雅。)

但是,Regex.Split 应该可以很好地完成这项工作。

例子:

var parts = Regex.Split(input, "aa", RegexOptions.IgnoreCase);

【讨论】:

  • 没问题。是的,它是框架中隐藏的小宝石之一。
  • Visual Basic 很容易做到这一点(使用Strings.Split)...我真的会后悔改用 C# 吗?
  • 仅供参考:在 C# 中,Regex.Split 使用分隔符。 stringVar.Split 没有
【解决方案2】:

如果你不关心大小写,那么最简单的做法是在使用拆分之前强制字符串全部大写或小写。

stringbits = datastring.ToLower().Split("aa")

如果您关心字符串中有趣位的大小写而不关心分隔符,那么我将使用 String.Replace 将所有分隔符强制为特定大小写(大写或小写,无关紧要),然后调用 String.Replace。使用分隔符的匹配大小写进行拆分。

strinbits = datastring.Replace("aA", "aa").Replace("AA", "aa").Split("aa")

【讨论】:

    【解决方案3】:

    在您的算法中,您可以使用String.IndexOf 方法并将OrdinalIgnoreCase 作为StringComparison 参数传入。

    【讨论】:

    • 那么没有办法利用String.Split?
    【解决方案4】:

    我的答案不如Noldorin's,但我会留下它,以便人们可以看到替代方法。这对于简单的拆分不太好,但如果您需要进行更复杂的解析,它会更加灵活。

    using System.Text.RegularExpressions;
    
    string data = "asdf aA asdfget aa uoiu AA";
    string aaRegex = "(.+?)[aA]{2}";
    
    MatchCollection mc = Regex.Matches(data, aaRegex);
    
    foreach(Match m in mc)
    {
        Console.WriteLine(m.Value);
    }
    

    【讨论】:

      【解决方案5】:

      这不是漂亮的版本,但也可以:

      "asdf aA asdfget aa uoiu AA".Split(new[] { "aa", "AA", "aA", "Aa" }, StringSplitOptions.RemoveEmptyEntries);
      

      【讨论】:

      • 是的,这就是我所说的排列 - 对于更长的拆分字符串来说,它变得相当麻烦。
      【解决方案6】:

      使用我的方法拆分

      public static string[] Split(this string s,string word,StringComparison stringComparison)
          {
              List<string> tmp = new List<string>();
              int wordSt;
              s.IndexOf(word, 0, stringComparison);
              while(s.IndexOf(word, 0, stringComparison) > -1)
              {
                  wordSt = s.IndexOf(word, 0, stringComparison);
                  tmp.Add(s.Substring(0, wordSt));
                  s = s.Substring(wordSt + word.Length);
              }
              tmp.Add(s);
              return tmp.ToArray();
          }
      

      【讨论】:

      • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
      【解决方案7】:
          public static List<string> _Split(this string input,string[] splt)
          {
              List<string> _Result=new List<string>();
              foreach(string _splt in splt)
              {
                  if (splt.Count() == 1)
                  { 
                      _Result.AddRange(Regex.Split(input, _splt, RegexOptions.IgnoreCase).ToList());
                  }
                  else 
                  {
                      List<string> NewStr = Regex.Split(input, _splt, RegexOptions.IgnoreCase).ToList();
                      foreach(string _NewStr in NewStr)
                      {
                          List<string> NewSplt = splt.ToList();
                          NewSplt.Remove(_splt);
                          return _Split(_NewStr, NewSplt.ToArray());
                      }
                  } 
              }
              return _Result;
          } 
      

      然后像下面这样使用这个函数

      public frmThematicConversation()
      {
          InitializeComponent();
          string str = "a b c d e f g h a b c f a d c b f";
          string[] splt = { "a", "b" };
          List<string> _result = str._Split(splt);
      }
      

      【讨论】:

        【解决方案8】:

        我编写的这个扩展方法取得了很好的成功,它使用.replace() 来查找和修复外壳。

        你这样称呼它:

        var result = source.Split(prefix, StringComparison.InvariantCultureIgnoreCase);
        

        扩展方法定义如下。

        public static string[] Split(this string source, string separator, 
            StringComparison comparison = StringComparison.CurrentCulture, 
            StringSplitOptions splitOptions = StringSplitOptions.None)
        {
            if (source is null || separator is null)
                return null;
        
            // Pass-through the default case.
            if (comparison == StringComparison.CurrentCulture)
                return source.Split(new string[] { separator }, splitOptions);
            
            // Use Replace to deal with the non-default comparison options.
            return source
                .Replace(separator, separator, comparison)
                .Split(new string[] { separator }, splitOptions);
        }
        

        注意:此方法处理我通常传递单个字符串分隔符的默认情况。

        【讨论】:

          【解决方案9】:
          Dim arr As String() = Strings.Split("asdf aA asdfget aa uoiu AA", 
                                              "aa" ,, CompareMethod.Text)
          

          CompareMethod.Text 忽略大小写。

          【讨论】:

          • 供更多读者参考;这是 VB 特有的,不适用于 C# (AFAIK)
          【解决方案10】:

          基于@Noldorin 的回答,我做了这个扩展方法。

          它接受多个分隔符字符串,并在您提供多个分隔符字符串时模仿string.Split(..) 的行为。它具有不变的('culture-unspecific')文化,当然会忽略案例。

          /// <summary>
          /// <see cref="string.Split(char[])"/> has no option to ignore casing.
          /// This functions mimics <see cref="string.Split(char[])"/> but also ignores casing.
          /// When called with <see cref="StringSplitOptions.RemoveEmptyEntries"/> <see cref="string.IsNullOrWhiteSpace(string)"/> is used to filter 'empty' entries.
          /// </summary>
          /// <param name="input">String to split</param>
          /// <param name="separators">Array of separators</param>
          /// <param name="options">Additional options</param>
          /// <returns></returns>
          public static IEnumerable<string> SplitInvariantIgnoreCase(this string input, string[] separators, StringSplitOptions options)
          {
              if (separators == null) throw new ArgumentNullException(nameof(separators));
              if (separators.Length <= 0) throw new ArgumentException("Value cannot be an empty collection.", nameof(separators));
              if (string.IsNullOrWhiteSpace(input)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(input));
          
              // Build a regex pattern of all the separators this looks like aa|bb|cc
              // The Pipe character '|' means alternative.
              var regexPattern = string.Join("|", separators);
          
              var regexSplitResult = Regex.Split(input, regexPattern, RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
          
              // NOTE To be honest - i don't know the exact behaviour of Regex.Split when it comes to empty entries.
              //      Therefore i doubt that filtering null values even matters - however for consistency i decided to code it in anyways.
              return options.HasFlag(StringSplitOptions.RemoveEmptyEntries) ? 
                  regexSplitResult.Where(c => !string.IsNullOrWhiteSpace(c)) 
                  : regexSplitResult;
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-01-21
            • 2018-01-03
            • 2013-05-10
            • 2017-05-29
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多