Как мне перейти из этой строки: "ThisIsMyCapsDelimitedString"
... к этой строке: "This Is My Caps Delimited String"
Наименьшее количество строк кода в VB.net предпочтительнее, но С# также приветствуется.
Ура!
Как мне перейти из этой строки: "ThisIsMyCapsDelimitedString"
... к этой строке: "This Is My Caps Delimited String"
Наименьшее количество строк кода в VB.net предпочтительнее, но С# также приветствуется.
Ура!
Я сделал это некоторое время назад. Он соответствует каждому компоненту имени CamelCase.
/([A-Z]+(?=$|[A-Z][a-z])|[A-Z]?[a-z]+)/g
Например:
"SimpleHTTPServer" => ["Simple", "HTTP", "Server"]
"camelCase" => ["camel", "Case"]
Чтобы преобразовать это, просто вставьте пробелы между словами:
Regex.Replace(s, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$1 ")
Если вам нужно обрабатывать цифры:
/([A-Z]+(?=$|[A-Z][a-z]|[0-9])|[A-Z]?[a-z]+|[0-9]+)/g
Regex.Replace(s,"([a-z](?=[A-Z]|[0-9])|[A-Z](?=[A-Z][a-z]|[0-9])|[0-9](?=[^0-9]))","$1 ")
Regex.Replace("ThisIsMyCapsDelimitedString", "(\\B[A-Z])", " $1")
Отличный ответ, MizardX! Я немного изменил его, чтобы обработать цифры как отдельные слова, так что "AddressLine1" станет "Адресной линией 1" вместо "Адресной строки1":
Regex.Replace(s, "([a-z](?=[A-Z0-9])|[A-Z](?=[A-Z][a-z]))", "$1 ")
Просто для небольшого разнообразия... Вот метод расширения, который не использует регулярное выражение.
public static class CamelSpaceExtensions
{
public static string SpaceCamelCase(this String input)
{
return new string(InsertSpacesBeforeCaps(input).ToArray());
}
private static IEnumerable<char> InsertSpacesBeforeCaps(IEnumerable<char> input)
{
foreach (char c in input)
{
if (char.IsUpper(c))
{
yield return ' ';
}
yield return c;
}
}
}
Грант Вагнер замечательный комментарий в стороне:
Dim s As String = RegularExpressions.Regex.Replace("ThisIsMyCapsDelimitedString", "([A-Z])", " $1")
Мне нужно решение, которое поддерживает аббревиатуры и числа. Это решение на основе Regex рассматривает следующие шаблоны как отдельные "слова":
Вы можете сделать это как однострочный:
Regex.Replace(value, @"(?<!^)((?<!\d)\d|(?(?<=[A-Z])[A-Z](?=[a-z])|[A-Z]))", " $1")
Более читаемый подход может быть лучше:
using System.Text.RegularExpressions;
namespace Demo
{
public class IntercappedStringHelper
{
private static readonly Regex SeparatorRegex;
static IntercappedStringHelper()
{
const string pattern = @"
(?<!^) # Not start
(
# Digit, not preceded by another digit
(?<!\d)\d
|
# Upper-case letter, followed by lower-case letter if
# preceded by another upper-case letter, e.g. 'G' in HTMLGuide
(?(?<=[A-Z])[A-Z](?=[a-z])|[A-Z])
)";
var options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Compiled;
SeparatorRegex = new Regex(pattern, options);
}
public static string SeparateWords(string value, string separator = " ")
{
return SeparatorRegex.Replace(value, separator + "$1");
}
}
}
Здесь выдержка из теста (XUnit):
[Theory]
[InlineData("PurchaseOrders", "Purchase-Orders")]
[InlineData("purchaseOrders", "purchase-Orders")]
[InlineData("2Unlimited", "2-Unlimited")]
[InlineData("The2Unlimited", "The-2-Unlimited")]
[InlineData("Unlimited2", "Unlimited-2")]
[InlineData("222Unlimited", "222-Unlimited")]
[InlineData("The222Unlimited", "The-222-Unlimited")]
[InlineData("Unlimited222", "Unlimited-222")]
[InlineData("ATeam", "A-Team")]
[InlineData("TheATeam", "The-A-Team")]
[InlineData("TeamA", "Team-A")]
[InlineData("HTMLGuide", "HTML-Guide")]
[InlineData("TheHTMLGuide", "The-HTML-Guide")]
[InlineData("TheGuideToHTML", "The-Guide-To-HTML")]
[InlineData("HTMLGuide5", "HTML-Guide-5")]
[InlineData("TheHTML5Guide", "The-HTML-5-Guide")]
[InlineData("TheGuideToHTML5", "The-Guide-To-HTML-5")]
[InlineData("TheUKAllStars", "The-UK-All-Stars")]
[InlineData("AllStarsUK", "All-Stars-UK")]
[InlineData("UKAllStars", "UK-All-Stars")]
Для большего разнообразия, используя простые старые объекты С#, следующее производит тот же вывод, что и @MizardX, отличное регулярное выражение.
public string FromCamelCase(string camel)
{ // omitted checking camel for null
StringBuilder sb = new StringBuilder();
int upperCaseRun = 0;
foreach (char c in camel)
{ // append a space only if we're not at the start
// and we're not already in an all caps string.
if (char.IsUpper(c))
{
if (upperCaseRun == 0 && sb.Length != 0)
{
sb.Append(' ');
}
upperCaseRun++;
}
else if( char.IsLower(c) )
{
if (upperCaseRun > 1) //The first new word will also be capitalized.
{
sb.Insert(sb.Length - 1, ' ');
}
upperCaseRun = 0;
}
else
{
upperCaseRun = 0;
}
sb.Append(c);
}
return sb.ToString();
}
string s = "ThisIsMyCapsDelimitedString";
string t = Regex.Replace(s, "([A-Z])", " $1").Substring(1);
Ниже представлен прототип, который преобразует следующее в заголовок:
Очевидно, вам понадобится только метод "ToTitleCase".
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
public class Program
{
public static void Main()
{
var examples = new List<string> {
"THEQuickBrownFox",
"theQUICKBrownFox",
"TheQuickBrownFOX",
"TheQuickBrownFox",
"the_quick_brown_fox",
"theFOX",
"FOX",
"QUICK"
};
foreach (var example in examples)
{
Console.WriteLine(ToTitleCase(example));
}
}
private static string ToTitleCase(string example)
{
var fromSnakeCase = example.Replace("_", " ");
var lowerToUpper = Regex.Replace(fromSnakeCase, @"(\p{Ll})(\p{Lu})", "$1 $2");
var sentenceCase = Regex.Replace(lowerToUpper, @"(\p{Lu}+)(\p{Lu}\p{Ll})", "$1 $2");
return new CultureInfo("en-US", false).TextInfo.ToTitleCase(sentenceCase);
}
}
Консоль будет следующей:
THE Quick Brown Fox The QUICK Brown Fox The Quick Brown FOX The Quick Brown Fox The Quick Brown Fox The FOX FOX QUICK
Наивное решение регулярных выражений. Не будет обрабатывать O'Conner и добавит пробел в начале строки.
s = "ThisIsMyCapsDelimitedString"
split = Regex.Replace(s, "[A-Z0-9]", " $&");
Вероятно, более элегантное решение, но это то, что я придумал с головы:
string myString = "ThisIsMyCapsDelimitedString";
for (int i = 1; i < myString.Length; i++)
{
if (myString[i].ToString().ToUpper() == myString[i].ToString())
{
myString = myString.Insert(i, " ");
i++;
}
}
Попробуйте использовать
"([A-Z]*[^A-Z]*)"
Результат будет соответствовать сочетанию алфавита с цифрами
Regex.Replace("AbcDefGH123Weh", "([A-Z]*[^A-Z]*)", "$1 ");
Abc Def GH123 Weh
Regex.Replace("camelCase", "([A-Z]*[^A-Z]*)", "$1 ");
camel Case
Реализация кода psudo: fooobar.com/questions/19525/...
private static StringBuilder camelCaseToRegular(string i_String)
{
StringBuilder output = new StringBuilder();
int i = 0;
foreach (char character in i_String)
{
if (character <= 'Z' && character >= 'A' && i > 0)
{
output.Append(" ");
}
output.Append(character);
i++;
}
return output;
}
Для соответствия между прописными буквами и Верхняя буква Unicode Category: (?<=\P{Lu})(?=\p{Lu})
Dim s = Regex.Replace("CorrectHorseBatteryStaple", "(?<=\P{Lu})(?=\p{Lu})", " ")
Regex примерно в 10-12 раз медленнее, чем простой цикл:
public static string CamelCaseToSpaceSeparated(this string str)
{
if (string.IsNullOrEmpty(str))
{
return str;
}
var res = new StringBuilder();
res.Append(str[0]);
for (var i = 1; i < str.Length; i++)
{
if (char.IsUpper(str[i]))
{
res.Append(' ');
}
res.Append(str[i]);
}
return res.ToString();
}