Was ist der beste Weg, um von Pascal Case (Upper Camel Case) in einen Satz umzuwandeln?
Zum Beispiel beginnend mit
"AwaitingFeedback"
und das umwandeln in
"Awaiting feedback"
C # vorzuziehen, aber ich könnte es von Java oder ähnlichem konvertieren.
Antworten:
public static string ToSentenceCase(this string str) { return Regex.Replace(str, "[a-z][A-Z]", m => m.Value[0] + " " + char.ToLower(m.Value[1])); }
In Versionen von Visual Studio nach 2015 können Sie dies tun
public static string ToSentenceCase(this string str) { return Regex.Replace(str, "[a-z][A-Z]", m => $"{m.Value[0]} {char.ToLower(m.Value[1])}"); }
Basierend auf: Konvertieren des Pascal-Falls in Sätze mit regulären Ausdrücken
quelle
Das funktioniert bei mir:
Regex.Replace(strIn, "([A-Z]{1,2}|[0-9]+)", " $1").TrimStart()
quelle
AwaitingTFeedback
oder beabsichtigenAwaiting9Feedback
. Jef Antwort ist besser für mich (die RenditenAwaiting T Feedback
undAwaiting9 Feedback
respectively).Ich werde es vorziehen, Humanizer dafür zu verwenden. Humanizer ist eine tragbare Klassenbibliothek, die alle Ihre .NET-Anforderungen zum Bearbeiten und Anzeigen von Zeichenfolgen, Aufzählungen, Datumsangaben, Zeiten, Zeiträumen, Zahlen und Mengen erfüllt.
Kurze Antwort
"AwaitingFeedback".Humanize() => Awaiting feedback
Lange und beschreibende Antwort
Humanizer kann viel mehr arbeiten. Andere Beispiele sind:
"PascalCaseInputStringIsTurnedIntoSentence".Humanize() => "Pascal case input string is turned into sentence" "Underscored_input_string_is_turned_into_sentence".Humanize() => "Underscored input string is turned into sentence" "Can_return_title_Case".Humanize(LetterCasing.Title) => "Can Return Title Case" "CanReturnLowerCase".Humanize(LetterCasing.LowerCase) => "can return lower case"
Der vollständige Code lautet:
using Humanizer; using static System.Console; namespace HumanizerConsoleApp { class Program { static void Main(string[] args) { WriteLine("AwaitingFeedback".Humanize()); WriteLine("PascalCaseInputStringIsTurnedIntoSentence".Humanize()); WriteLine("Underscored_input_string_is_turned_into_sentence".Humanize()); WriteLine("Can_return_title_Case".Humanize(LetterCasing.Title)); WriteLine("CanReturnLowerCase".Humanize(LetterCasing.LowerCase)); } } }
Ausgabe
Wenn Sie lieber Ihren eigenen C # -Code schreiben möchten, können Sie dies erreichen, indem Sie einige C # -Code-Inhalte schreiben, die bereits von anderen beantwortet wurden.
quelle
Bitte schön...
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CamelCaseToString { class Program { static void Main(string[] args) { Console.WriteLine(CamelCaseToString("ThisIsYourMasterCallingYou")); } private static string CamelCaseToString(string str) { if (str == null || str.Length == 0) return null; StringBuilder retVal = new StringBuilder(32); retVal.Append(char.ToUpper(str[0])); for (int i = 1; i < str.Length; i++ ) { if (char.IsLower(str[i])) { retVal.Append(str[i]); } else { retVal.Append(" "); retVal.Append(char.ToLower(str[i])); } } return retVal.ToString(); } } }
quelle
Dies ist genau wie @SSTA, aber effizienter als das Aufrufen von TrimStart.
Regex.Replace("ThisIsMyCapsDelimitedString", "(\\B[A-Z])", " $1")
quelle
Fand dies in der MvcContrib-Quelle, scheint hier noch nicht erwähnt zu sein.
return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim();
quelle
Hier ist eine grundlegende Methode, die ich mit Regex entwickelt habe
public static string CamelCaseToSentence(this string value) { var sb = new StringBuilder(); var firstWord = true; foreach (var match in Regex.Matches(value, "([A-Z][a-z]+)|[0-9]+")) { if (firstWord) { sb.Append(match.ToString()); firstWord = false; } else { sb.Append(" "); sb.Append(match.ToString().ToLower()); } } return sb.ToString(); }
Es werden auch Zahlen abgespalten, die ich nicht angegeben habe, die aber nützlich wären.
quelle
Nur weil alle Regex verwendet haben (außer diesem Typen ), ist hier eine Implementierung
StringBuilder
, die in meinen Tests etwa fünfmal schneller war . Beinhaltet auch die Überprüfung auf Zahlen."SomeBunchOfCamelCase2".FromCamelCaseToSentence == "Some Bunch Of Camel Case 2" public static string FromCamelCaseToSentence(this string input) { if(string.IsNullOrEmpty(input)) return input; var sb = new StringBuilder(); // start with the first character -- consistent camelcase and pascal case sb.Append(char.ToUpper(input[0])); // march through the rest of it for(var i = 1; i < input.Length; i++) { // any time we hit an uppercase OR number, it's a new word if(char.IsUpper(input[i]) || char.IsDigit(input[i])) sb.Append(' '); // add regularly sb.Append(input[i]); } return sb.ToString(); }
quelle
Ich würde einen regulären Ausdruck verwenden, ein Leerzeichen vor jedem Großbuchstaben einfügen und dann die gesamte Zeichenfolge verringern.
string spacedString = System.Text.RegularExpressions.Regex.Replace(yourString, "\B([A-Z])", " \k"); spacedString = spacedString.ToLower();
quelle
string camel = "MyCamelCaseString"; string s = Regex.Replace(camel, "([A-Z])", " $1").ToLower().Trim(); Console.WriteLine(s.Substring(0,1).ToUpper() + s.Substring(1));
Bearbeiten: hat Ihre Gehäuseanforderungen nicht bemerkt, entsprechend geändert. Sie könnten einen Matchevaluator verwenden, um das Gehäuse zu machen, aber ich denke, ein Teilstring ist einfacher. Sie können es auch in einen zweiten regulären Ausdruck ersetzen, in dem Sie das erste Zeichen ändern
"^\w"
nach oben
quelle
Dies ist in JavaScript (oder PHP usw.) einfach, wo Sie eine Funktion im Ersetzungsaufruf definieren können:
var camel = "AwaitingFeedbackDearMaster"; var sentence = camel.replace(/([A-Z].)/g, function (c) { return ' ' + c.toLowerCase(); }); alert(sentence);
Obwohl ich das anfängliche Cap-Problem nicht gelöst habe ... :-)
Nun zur Java-Lösung:
String ToSentence(String camel) { if (camel == null) return ""; // Or null... String[] words = camel.split("(?=[A-Z])"); if (words == null) return ""; if (words.length == 1) return words[0]; StringBuilder sentence = new StringBuilder(camel.length()); if (words[0].length() > 0) // Just in case of camelCase instead of CamelCase { sentence.append(words[0] + " " + words[1].toLowerCase()); } else { sentence.append(words[1]); } for (int i = 2; i < words.length; i++) { sentence.append(" " + words[i].toLowerCase()); } return sentence.toString(); } System.out.println(ToSentence("AwaitingAFeedbackDearMaster")); System.out.println(ToSentence(null)); System.out.println(ToSentence("")); System.out.println(ToSentence("A")); System.out.println(ToSentence("Aaagh!")); System.out.println(ToSentence("stackoverflow")); System.out.println(ToSentence("disableGPS")); System.out.println(ToSentence("Ahh89Boo")); System.out.println(ToSentence("ABC"));
Beachten Sie den Trick, den Satz zu teilen, ohne ein Zeichen zu verlieren ...
quelle
Pseudocode:
NewString = ""; Loop through every char of the string (skip the first one) If char is upper-case ('A'-'Z') NewString = NewString + ' ' + lowercase(char) Else NewString = NewString + char
Bessere Möglichkeiten können möglicherweise durch die Verwendung von Regex oder durch Routinen zum Ersetzen von Zeichenfolgen erreicht werden (ersetzen Sie 'X' durch 'x').
quelle
Eine xquery-Lösung, die sowohl für UpperCamel- als auch für LowerCamel-Fälle geeignet ist:
So geben Sie die Groß- und Kleinschreibung aus (nur das erste Zeichen des ersten Wortes wird groß geschrieben):
declare function content:sentenceCase($string) { let $firstCharacter := substring($string, 1, 1) let $remainingCharacters := substring-after($string, $firstCharacter) return concat(upper-case($firstCharacter),lower-case(replace($remainingCharacters, '([A-Z])', ' $1'))) };
So geben Sie die Groß- und Kleinschreibung des Titels aus (erstes Zeichen jedes großgeschriebenen Wortes):
declare function content:titleCase($string) { let $firstCharacter := substring($string, 1, 1) let $remainingCharacters := substring-after($string, $firstCharacter) return concat(upper-case($firstCharacter),replace($remainingCharacters, '([A-Z])', ' $1')) };
quelle
Ich habe etwas Ähnliches getan, und ich schätze es, mit dieser Diskussion einen Ausgangspunkt zu haben. Dies ist meine Lösung, die als Erweiterungsmethode für die Zeichenfolgenklasse im Kontext einer Konsolenanwendung platziert wird.
using System; using System.Text; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string piratese = "avastTharMatey"; string ivyese = "CheerioPipPip"; Console.WriteLine("{0}\n{1}\n", piratese.CamelCaseToString(), ivyese.CamelCaseToString()); Console.WriteLine("For Pete\'s sake, man, hit ENTER!"); string strExit = Console.ReadLine(); } } public static class StringExtension { public static string CamelCaseToString(this string str) { StringBuilder retVal = new StringBuilder(32); if (!string.IsNullOrEmpty(str)) { string strTrimmed = str.Trim(); if (!string.IsNullOrEmpty(strTrimmed)) { retVal.Append(char.ToUpper(strTrimmed[0])); if (strTrimmed.Length > 1) { for (int i = 1; i < strTrimmed.Length; i++) { if (char.IsUpper(strTrimmed[i])) retVal.Append(" "); retVal.Append(char.ToLower(strTrimmed[i])); } } } } return retVal.ToString(); } } }
quelle
Die meisten der vorhergehenden Antworten teilen Akronyme und Zahlen auf und fügen vor jedem Zeichen ein Leerzeichen ein. Ich wollte, dass Akronyme und Zahlen zusammengehalten werden, damit ich eine einfache Zustandsmaschine habe, die jedes Mal ein Leerzeichen ausgibt, wenn die Eingabe von einem Zustand in den anderen übergeht.
/// <summary> /// Add a space before any capitalized letter (but not for a run of capitals or numbers) /// </summary> internal static string FromCamelCaseToSentence(string input) { if (string.IsNullOrEmpty(input)) return String.Empty; var sb = new StringBuilder(); bool upper = true; for (var i = 0; i < input.Length; i++) { bool isUpperOrDigit = char.IsUpper(input[i]) || char.IsDigit(input[i]); // any time we transition to upper or digits, it's a new word if (!upper && isUpperOrDigit) { sb.Append(' '); } sb.Append(input[i]); upper = isUpperOrDigit; } return sb.ToString(); }
Und hier sind einige Tests:
[TestCase(null, ExpectedResult = "")] [TestCase("", ExpectedResult = "")] [TestCase("ABC", ExpectedResult = "ABC")] [TestCase("abc", ExpectedResult = "abc")] [TestCase("camelCase", ExpectedResult = "camel Case")] [TestCase("PascalCase", ExpectedResult = "Pascal Case")] [TestCase("Pascal123", ExpectedResult = "Pascal 123")] [TestCase("CustomerID", ExpectedResult = "Customer ID")] [TestCase("CustomABC123", ExpectedResult = "Custom ABC123")] public string CanSplitCamelCase(string input) { return FromCamelCaseToSentence(input); }
quelle
bool nextIsLower = i > 0 && i + 1 < source.Length && char.IsLower(source[i + 1]);
den if-Ausdruck hinzugefügt und in geändertif ((!upper || nextIsLower) && isUpperOrDigit)
. Dadurch werden Akronyme von Wörtern getrennt, sodass CustomABCWith123 zu Custom ABC With 123 anstelle von Custom ABCWith 123 wird . Es kann Fälle geben, die ich nicht behandelt habe, und natürlich arbeiten A und ich nicht.Meistens schon hier beantwortet
Kleine Änderung der akzeptierten Antwort, um den zweiten und die nachfolgenden Großbuchstaben in Kleinbuchstaben umzuwandeln
if (char.IsUpper(text[i])) newText.Append(' '); newText.Append(text[i]);
zu
if (char.IsUpper(text[i])) { newText.Append(' '); newText.Append(char.ToLower(text[i])); } else newText.Append(text[i]);
quelle