【问题标题】:Reverse case of all alphabetic characters in C# stringC#字符串中所有字母字符的反转
【发布时间】:2011-04-10 12:58:43
【问题描述】:

在 C# 字符串中反转所有字母字符的大小写的最简单方法是什么?例如“aBc1$;”应该变成“AbC1$;”我可以很容易地编写一个方法来做到这一点,但我希望有一个我不知道的库调用会使这更容易。我还想避免列出所有已知的字母字符并将每个字符与列表中的内容进行比较。也许这可以用正则表达式来完成,但我不太了解它们。谢谢。

感谢您的帮助。我为此创建了一个字符串扩展方法,主要受 Anthony Pegram 的解决方案启发,但没有 LINQ。我认为这在可读性和性能之间取得了很好的平衡。这是我想出的。

public static string SwapCase(this string source) {
    char[] caseSwappedChars = new char[source.Length];
    for(int i = 0; i < caseSwappedChars.Length; i++) {
        char c = source[i];
        if(char.IsLetter(c)) {
            caseSwappedChars[i] =
                char.IsUpper(c) ? char.ToLower(c) : char.ToUpper(c);
        } else {
            caseSwappedChars[i] = c;
        }
    }
    return new string(caseSwappedChars);
}

【问题讨论】:

  • 注意:我的回答中有一些国际化说明。

标签: c# regex case-sensitive


【解决方案1】:

您可以使用 LINQ 来完成。一种方法:

string input = "aBc1$";
string reversedCase = new string(
    input.Select(c => char.IsLetter(c) ? (char.IsUpper(c) ?
                      char.ToLower(c) : char.ToUpper(c)) : c).ToArray());

【讨论】:

    【解决方案2】:

    如果您不关心国际化:

    string input = "aBc1$@[\\]^_{|{~";
    Encoding enc = new System.Text.ASCIIEncoding();
    byte[] b = enc.GetBytes(input);
    for (int i = input.Length - 1; i >= 0; i -= 1) {
       if ((b[i] & 0xdf) >= 65 && (b[i] & 0xdf) <= 90) { //check if alpha
          b[i] ^= 0x20; // then XOR the correct bit to change case
       }
    }
    Console.WriteLine(input);
    Console.WriteLine(enc.GetString(b));
    

    另一方面,如果您确实关心国际化,则需要将 CultureInfo.InvariantCulture 传递给您的 ToUpper() 和 ToLower() 函数...

    【讨论】:

    • 这是一个很多人不知道的 XOR 的好技巧。任何被 32 (0x20) 异或的字母都会产生相反的情况。
    • @Kibbee 感谢您的解释。我可能应该在我的帖子中。无论如何,这个技巧只适用于普通的旧 ASCII 字符...
    【解决方案3】:

    如果你不懂 LINQ,你可以用老派的方式来做。

    static string InvertCasing(string s)
    {
        char[] c = s.ToCharArray();
        char[] cUpper = s.ToUpper().ToCharArray();
        char[] cLower = s.ToLower().ToCharArray();
    
        for (int i = 0; i < c.Length; i++)
        {
            if (c[i] == cUpper[i])
            {
                c[i] = cLower[i];
            }
            else
            {
                c[i] = cUpper[i];
            }
        }
    
        return new string(c);
    }
    

    【讨论】:

      【解决方案4】:

      这是一个正则表达式方法:

      string input = "aBcdefGhI123jKLMo$";
      string result = Regex.Replace(input, "[a-zA-Z]",
                                  m => Char.IsUpper(m.Value[0]) ?
                                       Char.ToLower(m.Value[0]).ToString() :
                                       Char.ToUpper(m.Value[0]).ToString());
      Console.WriteLine("Original: " + input);
      Console.WriteLine("Modified: " + result);
      

      您可以使用Char.Parse(m.Value) 作为m.Value[0] 的替代品。另外,请注意改用ToUpperInvariantToLowerInvariant 方法。有关更多信息,请参阅此问题:In C# what is the difference between ToUpper() and ToUpperInvariant()?

      【讨论】:

        【解决方案5】:
                char[] carr = str.ToCharArray();
                for (int i = 0; i < carr.Length; i++)
                {
                    if (char.IsLetter(carr[i]))
                    {
                        carr[i] = char.IsUpper(carr[i]) ? char.ToLower(carr[i]) : char.ToUpper(carr[i]);
                    }
                }
                str = new string(carr);
        

        【讨论】:

          【解决方案6】:

          昨天我被问到一个类似的问题,我的回答是:

          public static partial class StringExtensions {
              public static String InvertCase(this String t) {
                  Func<char, String> selector=
                      c => (char.IsUpper(c)?char.ToLower(c):char.ToUpper(c)).ToString();
          
                  return t.Select(selector).Aggregate(String.Concat);
              }
          }
          

          您可以轻松更改方法签名以添加CultureInfo 类型的参数,并将其与char.ToUpper 等方法一起使用以满足全球化的要求。

          【讨论】:

            【解决方案7】:

            比这里列出的其他一些方法快一点,而且很好,因为它使用 Char 算法!

                var line = "someStringToSwapCase";
            
                var charArr = new char[line.Length];
            
                for (int i = 0; i < line.Length; i++)
                {
                    if (line[i] >= 65 && line[i] <= 90)
                    {
                        charArr[i] = (char)(line[i] + 32);
                    }
                    else if (line[i] >= 97 && line[i] <= 122)
                    {
                        charArr[i] = (char)(line[i] - 32);
                    }
                    else
                    {
                        charArr[i] = line[i];
                    }
                }
            
                var res = new String(charArr);
            

            【讨论】:

              【解决方案8】:

              我为字符串做了一个扩展方法!

              public static class InvertStringExtension
              {
                  public static string Invert(this string s)
                  {
                      char[] chars = s.ToCharArray();
                      for (int i = 0; i < chars.Length; i++)
                          chars[i] = chars[i].Invert();
              
                      return new string(chars);
                  }
              }
              
              public static class InvertCharExtension
              {
                  public static char Invert(this char c)
                  {
                      if (!char.IsLetter(c))
                          return c;
              
                      return char.IsUpper(c) ? char.ToLower(c) : char.ToUpper(c);
                  }
              }
              

              使用

              var hello = "hELLO wORLD";
              var helloInverted = hello.Invert();
              
              // helloInverted == "Hello World"
              

              【讨论】:

                【解决方案9】:

                这将帮助你更多..因为这里我没有直接使用函数。

                using System;
                using System.Collections.Generic;
                using System.Linq;
                using System.Text;
                using System.Threading.Tasks;
                
                namespace Practice
                {
                    class Program
                    {
                        static void Main(string[] args)
                        {
                            char[] new_str = new char[50];
                            string str;
                            int ch;
                            Console.Write("Enter String : ");
                            str = Console.ReadLine();
                
                            for (int i = 0; i < str.Length; i++)
                            {
                                ch = (int)str[i];
                                if (ch > 64 && ch < 91)
                                {
                                    ch = ch + 32;
                                    new_str[i] = Convert.ToChar(ch);
                                }
                                else
                                {
                                    ch = ch - 32;
                                    new_str[i] = Convert.ToChar(ch);
                                }
                            }
                            Console.Write(new_str);
                
                            Console.ReadKey();
                        }
                    }
                }
                

                我相信这也适用于你。谢谢。

                【讨论】:

                  【解决方案10】:

                  下面的代码只对每个字母进行 2 次函数调用。我们不检查是否为 IsLetter,而是在必要时应用大写/小写。

                      string result="";
                      foreach (var item in S)
                          {
                          if (char.ToLower(item) != item )
                              result+= char.ToLower(item);
                          else
                              result+= char.ToUpper(item);
                          }
                  

                  也可以(尽管可读性较差)创建一个额外的变量并将其设置为 char.ToLower(item) 在检查之前,用一个函数调用交换一个额外的变量,顺便说一句:

                      string result="";
                      foreach (var item in S)
                          {
                          var temp=char.ToLower(item);
                          if (temp != item )
                              result+= temp;
                          else
                              result+= char.ToUpper(item);
                          }
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2015-02-26
                    • 2022-01-09
                    • 2012-10-10
                    • 2020-02-07
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-06-22
                    • 1970-01-01
                    相关资源
                    最近更新 更多