Лучший способ превратить дело Паскаля в предложение
Каков наилучший способ конвертировать из Case Pascal (верхний случай верблюда) в предложение.
Например, начиная с
"AwaitingFeedback"
и преобразуя его в
"Awaiting feedback"
С# предпочтительнее, но я мог бы преобразовать его из Java или аналогичного.
Ответы
Ответ 1
public static string ToSentenceCase(this string str)
{
return Regex.Replace(str, "[a-z][A-Z]", m => m.Value[0] + " " + char.ToLower(m.Value[1]));
}
В версиях visual studio после 2015 года вы можете сделать
public static string ToSentenceCase(this string str)
{
return Regex.Replace(str, "[a-z][A-Z]", m => $"{m.Value[0]} {char.ToLower(m.Value[1])}");
}
На основе: Преобразование случая Паскаля в предложения с использованием регулярного выражения
Ответ 2
Здесь вы идете...
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();
}
}
}
Ответ 3
Это работает для меня:
Regex.Replace(strIn, "([A-Z]{1,2}|[0-9]+)", " $1").TrimStart()
Ответ 4
Я предпочитаю использовать Humanizer для этого. Humanizer - это переносимая библиотека классов, которая отвечает всем вашим потребностям .NET для управления и отображения строк, перечислений, дат, времени, временных интервалов, чисел и количеств.
Короткий ответ
"AwaitingFeedback".Humanize() => Awaiting feedback
Длинный и описательный ответ
Humanizer может сделать намного больше работы, другие примеры:
"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"
Полный код:
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));
}
}
}
Выход
В ожидании обратной связи
Строка ввода регистра Pascal превращается в предложение
Подчеркнутая входная строка превращается в предложение.
может вернуть нижний регистр
Если вы предпочитаете писать свой собственный код С#, вы можете достичь этого, написав кое-что из кода С#, как уже отвечали другие.
Ответ 5
Это как @SSTA, но более эффективно, чем вызов TrimStart.
Regex.Replace("ThisIsMyCapsDelimitedString", "(\\B[A-Z])", " $1")
Ответ 6
Обнаружено это в источнике MvcContrib, пока не упоминается здесь.
return Regex.Replace(input, "([A-Z])", " $1", RegexOptions.Compiled).Trim();
Ответ 7
Вот основной способ сделать это, что я придумал использование Regex
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();
}
Он также отделит числа, которые я не указал, но был бы полезен.
Ответ 8
Я бы использовал регулярное выражение, вставив пробел перед каждым символом верхнего регистра, а затем опустив всю строку.
string spacedString = System.Text.RegularExpressions.Regex.Replace(yourString, "\B([A-Z])", " \k");
spacedString = spacedString.ToLower();
Ответ 9
Это легко сделать в JavaScript (или PHP и т.д.), где вы можете определить функцию в вызове replace:
var camel = "AwaitingFeedbackDearMaster";
var sentence = camel.replace(/([A-Z].)/g, function (c) { return ' ' + c.toLowerCase(); });
alert(sentence);
Хотя я не решил проблему с начальным кэшем...: -)
Теперь для решения Java:
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"));
Обратите внимание на трюк, чтобы разделить предложение без потери символа...
Ответ 10
string camel = "MyCamelCaseString";
string s = Regex.Replace(camel, "([A-Z])", " $1").ToLower().Trim();
Console.WriteLine(s.Substring(0,1).ToUpper() + s.Substring(1));
Изменить: не заметили ваши требования к обсадной колонне, соответственно изменили. Вы можете использовать matchevaluator для создания оболочки, но я думаю, что подстрока проще. Вы также можете обернуть его во вторую замену регулярного выражения, где вы меняете первый символ
"^\w"
до верхнего
\U (i think)
Ответ 11
Псевдо-код:
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
Возможно, более эффективные способы можно использовать с помощью регулярных выражений или подпрограмм замены строк (замените "X" на "x" )
Ответ 12
Решение xquery, которое работает как в случае с UpperCamel, так и в нижней камере:
Для вывода предложения (только первый символ первого слова заглавный):
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')))
};
Чтобы вывести заголовок (первый символ каждого заглавного слова):
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'))
};
Ответ 13
Нашел себе что-то подобное, и я очень благодарен за то, что он был в этом обсуждении. Это мое решение, помещенное как метод расширения в класс строки в контексте консольного приложения.
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\ 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();
}
}
}
Ответ 14
Просто потому, что все использовали Regex (кроме этого парня), здесь реализация с StringBuilder
которая была примерно в 5 раз быстрее в моих тестах. Включает проверку номеров тоже.
"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 a new word
if(char.IsUpper(input[i]) || char.IsDigit(input[i])) sb.Append(' ');
// add regularly
sb.Append(input[i]);
}
return sb.ToString();
}
Ответ 15
В основном уже ответил здесь
Малый chage к принятому ответу, чтобы преобразовать вторую и последующие заглавные буквы в нижний регистр, поэтому измените
if (char.IsUpper(text[i]))
newText.Append(' ');
newText.Append(text[i]);
to
if (char.IsUpper(text[i]))
{
newText.Append(' ');
newText.Append(char.ToLower(text[i]));
}
else
newText.Append(text[i]);
Ответ 16
Большинство предыдущих ответов разбивают аббревиатуры и цифры, добавляя пробел перед каждым символом. Я хотел, чтобы сокращения и числа были вместе, поэтому у меня есть простой конечный автомат, который испускает пробел каждый раз, когда входные данные переходят из одного состояния в другое.
/// <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 a new word
if (!upper && isUpperOrDigit)
{
sb.Append(' ');
}
sb.Append(input[i]);
upper = isUpperOrDigit;
}
return sb.ToString();
}
И вот несколько тестов:
[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);
}