Обратный регистр всех буквенных символов в строке C#

каков самый простой способ обратить вспять случай всех алфавитных символов в строке c#? Например, "aBc1$;" должен стать "AbC1$;" я мог бы легко написать метод, который делает это, но я надеюсь, что есть вызов библиотеки, о котором я не знаю, что облегчит это. Я также хотел бы избежать списка всех известных алфавитных символов и сравнения каждого символа с тем, что есть в списке. Возможно, это можно сделать с регулярными выражениями, но я их не очень хорошо знаю. Спасибо.

Спасибо за помощь. Я создал метод расширения строки для этого, который в основном вдохновлен решением Энтони Пеграма, но без 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);
}

9 ответов


вы можете сделать это в строке с 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());

Если вы не заботитесь об интернационализации:

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 ()...


вы можете сделать это старой школы, если вы не знаете 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);
}

вот подход regex:

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]. Кроме того, помните об использовании ToUpperInvariant и методы. Для получения дополнительной информации см. Этот вопрос:в C# в чем разница между ToUpper() и ToUpperInvariant()?


        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);

мне вчера задали аналогичный вопрос, и мой ответ такой:

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 на требования глобализации.


немного быстрее, чем некоторые другие методы, перечисленные здесь, и это хорошо, потому что он использует арифметику 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);

Я создал метод расширения для строк, который делает именно это!

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"

Это поможет вам больше.. потому что здесь я не использую непосредственно функцию.

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();
        }
    }
}

Я уверен, что это также будет работать для вас.. Спасибо.