2010-09-10 20 views
6

Jaki jest najprostszy sposób odwrócenia przypadku wszystkich znaków alfabetu w ciągu C#? Na przykład "aBc1 $;" powinno stać się "AbC1 $;" Mogłabym łatwo napisać metodę, która to robi, ale mam nadzieję, że wywołanie biblioteki, o którym nie wiem, ułatwiłoby to. Chciałbym również uniknąć listy wszystkich znanych znaków alfabetu i porównywania każdej postaci z tym, co jest na liście. Może to zrobić za pomocą wyrażeń regularnych, ale nie znam ich zbyt dobrze. Dzięki.Odwrotność wszystkich znaków alfabetu w ciągu C#

Dzięki za pomoc. Stworzyłem metodę rozszerzenia ciągów, która jest w większości inspirowana rozwiązaniem Anthony Pegram, ale bez LINQ. Wydaje mi się, że zapewnia to odpowiednią równowagę pomiędzy czytelnością i wydajnością. Oto, co wymyśliłem.

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); 
} 
+0

Uwaga: niektóre uwagi dotyczące internacjonalizacji znajdują się w mojej odpowiedzi. – ErikE

Odpowiedz

17

Można to zrobić w linii z LINQ. Jedna metoda:

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

Podoba mi się to, dzięki! –

+0

@INTPnerd Jeśli sprawy powracają powoli, możesz przyjrzeć się innym metodom ... – ErikE

1

Możesz zrobić to oldschoolowo, jeśli nie znasz 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); 
} 
1

Oto regex podejście:

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

Można użyć Char.Parse(m.Value) jako alternatywny do m.Value[0]. Należy również pamiętać o zastosowaniu metod. Więcej informacji można znaleźć na to pytanie: In C# what is the difference between ToUpper() and ToUpperInvariant()?

5

Jeśli nie dbają o internacjonalizacji:

string input = "[email protected][\\]^_{|{~"; 
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)); 

Jeśli, z drugiej strony, to dbam o internacjonalizacji, będziemy chcieli, aby przejść do w CultureInfo.InvariantCulture Twój ToUpper() i Metoda ToLower() funkcje ...

+2

To jest dobra sztuczka z XOR, o której wielu ludzi nie wie. Każda litera XORED o wartości 32 (0x20) spowoduje odwrócenie tej wielkości. – Kibbee

+0

@ Kibbee dzięki za wyjaśnienie. Prawdopodobnie powinienem mieć w moim poście. W każdym razie ta sztuczka działa tylko dla zwykłych starych znaków ASCII ... – ErikE

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

i został poproszony podobne pytanie wczoraj i moja odpowiedź brzmi tak:

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

Możesz łatwo zmienić podpis metody, dodając parametr typu CultureInfo i używać go z metodami takimi jak char.ToUpper, aby spełnić wymagania globalizacji.

0

Trochę szybszy niż niektóre inne metody wymienione tutaj i jest ładny, ponieważ wykorzystuje arytmetykę 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); 
0

Zrobiłem metodę rozszerzenia dla ciągów, które robi właśnie to!

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

Aby korzystać

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

// helloInverted == "Hello World" 
0

Będzie to pomaga więcej .. bo ja tu nie używać bezpośrednio funkcjonować.

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

Jestem pewny, że to również zadziała dla Ciebie .. Dziękuję.

Powiązane problemy