【问题标题】:String normalisation字符串规范化
【发布时间】:2010-10-10 22:15:08
【问题描述】:

我正在编写一些需要进行字符串规范化的代码,我想将给定的字符串转换为驼峰式表示(嗯,至少最好的猜测)。示例:

"the quick brown fox" => "TheQuickBrownFox"
"the_quick_brown_fox" => "TheQuickBrownFox"
"123The_quIck bROWN FOX" => "TheQuickBrownFox"
"the_quick brown fox 123" => "TheQuickBrownFox123"
"thequickbrownfox" => "Thequickbrownfox"

我认为您应该能够从这些示例中获得想法。我想去掉所有 特殊 字符('、"、!、@、. 等),将每个单词(单词由空格、_ 或 - 定义)和任何 前导数字 下降(尾随/内部都可以,但这个要求并不重要,具体取决于难度)。

我正在尝试找出实现这一目标的最佳方法。我的第一个猜测是使用正则表达式,但我的正则表达式技能充其量是不好的,所以我真的不知道从哪里开始。

我的另一个想法是循环和解析数据,比如将其分解为 单词,解析每个单词,然后以这种方式重建字符串。

或者还有其他方法可以解决吗?

【问题讨论】:

    标签: c# .net-3.5 string normalization


    【解决方案1】:

    觉得尝试一下会很有趣,这就是我想出的:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                StringBuilder sb = new StringBuilder();
                string sentence = "123The_quIck bROWN FOX1234";
    
                sentence = sentence.ToLower();
    
                char[] s = sentence.ToCharArray();
    
                bool atStart = true;
                char pChar = ' ';
    
                char[] spaces = { ' ', '_', '-' };
                char a;
                foreach (char c in s)
                {
                    if (atStart && char.IsDigit(c)) continue;
    
                    if (char.IsLetter(c))
                    {
                        a = c;
                        if (spaces.Contains(pChar))
                            a = char.ToUpper(a);
                        sb.Append(a);
                        atStart = false;
                    }
                    else if(char.IsDigit(c))
                    {
                        sb.Append(c);
                    }
                    pChar = c;
                }
    
                Console.WriteLine(sb.ToString());
                Console.ReadLine();
            }
        }
    }
    

    【讨论】:

    • 天啊,我想你和我几乎到了同一个地方!
    【解决方案2】:

    此正则表达式匹配所有单词。然后,我们 Aggregate 他们使用大写第一个字符的方法,ToLowers 字符串的其余部分。

    Regex regex = new Regex(@"[a-zA-Z]*", RegexOptions.Compiled);
    
    private string CamelCase(string str)
    {
        return regex.Matches(str).OfType<Match>().Aggregate("", (s, match) => s + CamelWord(match.Value));
    }
    
    private string CamelWord(string word)
    {
        if (string.IsNullOrEmpty(word))
            return "";
    
        return char.ToUpper(word[0]) + word.Substring(1).ToLower();
    }
    

    顺便说一下,这个方法忽略了数字。要添加它们,您可以将正则表达式更改为 @"[a-zA-Z]*|[0-9]*",我想 - 但我还没有测试过。

    【讨论】:

      【解决方案3】:

      在 Microsoft.VisualBasic 命名空间中使用 Strings.StrConv 的简单解决方案怎么样? (不要忘记添加对 Microsoft.VisualBasic 的项目引用):

      using System;
      using VB = Microsoft.VisualBasic;
      
      
      namespace ConsoleApplication1
      {
          class Program
          {
              static void Main(string[] args)
              {
                  Console.WriteLine(VB.Strings.StrConv("QUICK BROWN", VB.VbStrConv.ProperCase, 0));
                  Console.ReadLine();
              }
          }
      }
      

      【讨论】:

      • 谢谢,那+其他解决方案处理其他无效的做得很好
      【解决方案4】:

      任何涉及匹配特定字符的解决方案都可能不适用于某些字符编码,尤其是在使用 Unicode 表示时,它包含数十个空格字符、数千个“符号”、数千个标点字符、数千个“字母”等。最好尽可能使用内置的 Unicode 感知功能。至于什么是“特殊字符”,你可以根据Unicode categories 来决定。例如,它会包含“标点符号”,但会包含“符号”吗?

      ToLower()、IsLetter() 等应该没问题,并考虑到 Unicode 中所有可能的字母。对破折号和斜杠的匹配可能应该考虑 Unicode 中的几十个空格和破折号字符中的一些。

      【讨论】:

        【解决方案5】:

        你可以wear ruby slippers to work :)

        def camelize str
          str.gsub(/^[^a-zA-z]*/, '').split(/[^a-zA-Z0-9]/).map(&:capitalize).join
        end
        

        【讨论】:

          猜你喜欢
          • 2018-09-29
          • 2020-02-12
          • 2012-04-25
          • 1970-01-01
          • 2013-06-29
          • 2019-04-19
          • 2014-05-10
          • 2016-07-06
          • 1970-01-01
          相关资源
          最近更新 更多