2010-09-10 25 views
6

¿Cuál es la forma más sencilla de revertir el caso de todos los caracteres alfabéticos en una cadena C#? Por ejemplo "aBc1 $;" debería convertirse en "AbC1 $"; Podría escribir fácilmente un método que hace esto, pero estoy esperando que haya una llamada a la biblioteca que no sé que haría que esto sea más fácil. También me gustaría evitar tener una lista de todos los caracteres alfabéticos conocidos y comparar cada carácter con lo que está en la lista. Tal vez esto se puede hacer con expresiones regulares, pero no los conozco muy bien. Gracias.Causa inversa de todos los caracteres alfabéticos en C# cadena

Gracias por la ayuda. Creé un método de extensión de cadena para esto que está principalmente inspirado en la solución de Anthony Pegram, pero sin el LINQ. Creo que esto logra un buen equilibrio entre legibilidad y rendimiento. Esto es lo que se me ocurrió.

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

Nota: algunas notas de internacionalización en mi respuesta. – ErikE

Respuesta

17

Puede hacerlo en línea con LINQ. Un método:

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

Me gusta esto, gracias! –

+0

@INTPnerd Si las cosas se vuelven lentas, podría buscar otros métodos ... – ErikE

1

Puedes hacerlo de la vieja escuela si no conoces 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

Aquí es un enfoque de expresiones regulares:

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

Usted puede utilizar Char.Parse(m.Value) como una alternativa a m.Value[0]. Además, tenga en cuenta el uso de los métodos ToUpperInvariant y ToLowerInvariant. Para más información ver esta pregunta: In C# what is the difference between ToUpper() and ToUpperInvariant()?

5

Si no se preocupan por la internacionalización:

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

Si, por el contrario, que se preocupan por la internacionalización, tendrá que pasar en CultureInfo.InvariantCulture a su ToUpper() y ToLower() funciones ...

+2

Este es un buen truco con el XOR que mucha gente desconoce. Cualquier letra XORed por 32 (0x20) producirá el caso inverso. – Kibbee

+0

@Kibbee gracias por explicarme. Probablemente debería tener en mi publicación. De todos modos, este truco solo funciona para viejos personajes ASCII simples ... – 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

me pidieron una pregunta similar ayer y mi respuesta es como:

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

Puede cambiar fácilmente la firma del método para agregar un parámetro del tipo CultureInfo, y utilizarlo con métodos como char.ToUpper para un requisito de globalización.

0

Un poco más rápido que algunos otros métodos enumerados aquí y es bueno porque utiliza aritmética 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

Hice un método de extensión para cadenas que hace esto!

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

Para utilizar

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

// helloInverted == "Hello World" 
0

Esto le ayuda a más .. porque aquí no he utilizar directamente la función.

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

Estoy seguro de que esto también le servirá ... Gracias.

Cuestiones relacionadas