2016-07-13 37 views
11

.NET Framework ha un metodo TextInfo.ToTitleCase.Metodo integrato per convertire una stringa in title case?

C'è qualcosa di equivalente in .NET Core?

Modifica: sto cercando un metodo integrato in .NET Core.

+0

Questo è il codice nell'origine di riferimento, ma non sembra banale da copiare nel proprio progetto. Potresti provare, però. http://referencesource.microsoft.com/#mscorlib/system/globalization/textinfo.cs,5f96501d72edadce –

+2

Possibile duplicato di [Trasforma stringa in caso titolo] (http://stackoverflow.com/questions/23860116/transform-string- to-title-case) – Eser

+5

@Eser non è un problema, Q non ha nulla a che fare con .NET Core – mxmissile

risposta

4

.NET standard 2.0 aggiunto TextInfo.ToTitleCase (source), in modo da poter utilizzare in .NET 2.0 Nucleo.

Per supporto .NET Core 1.x, tuttavia, si è fuori di fortuna.

21

È possibile implementare il proprio metodo di estensione:

public static class StringHelper 
{ 
    public static string ToTitleCase(this string str) 
    { 
     var tokens = str.Split(new[] { " ", "-" }, StringSplitOptions.RemoveEmptyEntries); 
     for (var i = 0; i < tokens.Length; i++) 
     { 
      var token = tokens[i]; 
      tokens[i] = token == token.ToUpper() 
       ? token 
       : token.Substring(0, 1).ToUpper() + token.Substring(1).ToLower(); 
     } 

     return string.Join(" ", tokens); 
    } 
} 

credito: forma blatently copiato questo gist *.

* Aggiunto il bit per gli acronimi Dotnet Fiddle.

+0

Questo non fa l'intestazione del titolo "corretta", tuttavia nemmeno il vecchio metodo .net. – mxmissile

+4

l'OP richiede una sostituzione per 'TextInfo.ToTitleCase', non per un _proper title casing_, quindi questa risposta è corretta. E funziona anche bene. –

+0

Questa soluzione non gestisce tutti i casi gestiti da ToTitleCase. Vedi la mia soluzione. – DeadlyChambers

10

Sembra che non ci sia un tale metodo integrato in .NET Core.

1

Sfortunatamente, ancora nell'ottobre 2016, .NET Core non ci fornisce un metodo ToTitleCase.

Ne ho creato uno che funziona per le mie esigenze. Puoi regolarlo aggiungendo i tuoi delimitatori alle espressioni regolari. Sostituisci _cultureInfo con l'istanza CultureInfo applicabile a te.

public static class TextHelper 
{ 
    private static readonly CultureInfo _cultureInfo = CultureInfo.InvariantCulture; 

    public static string ToTitleCase(this string str) 
    { 
     var tokens = Regex.Split(_cultureInfo.TextInfo.ToLower(str), "([ -])"); 

     for (var i = 0; i < tokens.Length; i++) 
     { 
      if (!Regex.IsMatch(tokens[i], "^[ -]$")) 
      { 
       tokens[i] = $"{_cultureInfo.TextInfo.ToUpper(tokens[i].Substring(0, 1))}{tokens[i].Substring(1)}"; 
      } 
     } 

     return string.Join("", tokens); 
    } 
} 
+0

Questa soluzione non gestisce gli acronimi https://dotnetfiddle.net/Suwfcg – DeadlyChambers

+0

Prova a rimuovere il metodo 'ToLower()' se questo funziona per le tue esigenze specifiche. – silkfire

+0

Non so cosa intendi? La rimozione di ToLower causa errori di compilazione. ToLower e ToUpper sono le uniche opzioni che vedo. Anche in questo caso questa soluzione non gestisce gli acronimi. – DeadlyChambers

1

ho creato un github per l'estensione con i test, e un dotnet fiddle che comprende le altre soluzioni di questo post. Dovrai decommentare le righe per vedere cosa producono le altre soluzioni. Questa soluzione ha coperto tutti gli scenari che mi venivano in mente. Puoi verificarli nei test sul git o sul violino. Suggerisco di utilizzare questa soluzione se si desidera ottenere un output simile a TextInfo.ToTitleCase in non .NET Core.

public static class StringExtension 
{ 
    /// <summary> 
    /// Should capitalize the first letter of each word. Acronyms will stay uppercased. 
    /// Anything after a non letter or number will keep be capitalized. 
    /// </summary> 
    /// <param name="str"></param> 
    /// <returns></returns> 
    public static string ToTitleCase(this string str) 
    { 
     var tokens = str.Split(new[] { " " }, StringSplitOptions.None); 
     var stringBuilder = new StringBuilder(); 
     for (var ti = 0; ti < tokens.Length; ti++) 
     { 
      var token = tokens[ti]; 
      if (token == token.ToUpper()) 
       stringBuilder.Append(token + " "); 
      else 
      { 
       var previousWasSeperator = false; 
       var previousWasNumber = false; 
       var ignoreNumber = false; 
       for (var i = 0; i < token.Length; i++) 
       { 

        if (char.IsNumber(token[i])) 
        { 
         stringBuilder.Append(token[i]); 
         previousWasNumber = true; 
        } 
        else if (!char.IsLetter(token[i])) 
        { 
         stringBuilder.Append(token[i]); 
         previousWasSeperator = true; 
        } 
        else if ((previousWasNumber && !ignoreNumber) || previousWasSeperator) 
        { 
         stringBuilder.Append(char.ToUpper(token[i])); 
         previousWasSeperator = false; 
         previousWasNumber = false; 
        } 
        else if (i == 0) 
        { 
         ignoreNumber = true; 
         stringBuilder.Append(char.ToUpper(token[i])); 
        } 
        else 
        { 
         ignoreNumber = true; 
         stringBuilder.Append(char.ToLower(token[i])); 
        } 
       } 
       stringBuilder.Append(" "); 
      } 
     } 
     return stringBuilder.ToString().TrimEnd(); 
    } 
} 
Problemi correlati