[英]Ignore existing spaces in converting CamelCase to string with spaces
我想將camelCase
或PascalCase
單詞拆分為多個單獨的單詞集合。
到目前為止,我有:
Regex.Replace(value, @"(\B[A-Z]+?(?=[A-Z][^A-Z])|\B[A-Z]+?(?=[^A-Z]))", " $0", RegexOptions.Compiled);
它可以很好地將“ TestWord”轉換為“ Test Word”,並使單個單詞保持不變,例如, Testing
仍然為Testing
。
然而, ABCTest
被轉換到ABC Test
時,我寧願ABC Test
。
嘗試:
[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z])|[a-z]+|[A-Z]+
string strText = " TestWord asdfDasdf ABCDef";
string[] matches = Regex.Matches(strText, @"[A-Z][a-z]+|[A-Z]+(?=[A-Z][a-z])|[a-z]+|[A-Z]+")
.Cast<Match>()
.Select(m => m.Value)
.ToArray();
string result = String.Join(" ", matches);
result
= 'Test Word asdf Dasdf ABC Def'
在示例字符串中:
TestWord qwerDasdf
ABCTest Testing ((*&^%$CamelCase!"£$%^^))
asdfAasdf
AaBbbCD
[AZ][az]+
符合項:
Test
Word
Dasdf
Test
Testing
Camel
Case
Aasdf
Aa
Bbb
[AZ]+(?=[AZ][az])
符合:
ABC
[az]+
符合項:
qwer
asdf
[AZ]+
符合項:
CD
這是我的嘗試:
(?<!^|\b|\p{Lu})\p{Lu}+(?=\p{Ll}|\b)|(?<!^\p{Lu}*|\b)\p{Lu}(?=\p{Ll}|(?<!\p{Lu}*)\b)
此正則表達式可與Regex.Replace
和$0
用作替換字符串。
Regex.Replace(value, @"(?<!^|\b|\p{Lu})\p{Lu}+(?=\p{Ll}|\b)|(?<!^\p{Lu}*|\b)\p{Lu}(?=\p{Ll}|(?<!\p{Lu}*)\b)", " $0", RegexOptions.Compiled);
觀看演示
正則表達式說明:
(?<!^|\\b|\\p{Lu})\\p{Lu}+(?=\\p{Ll}|\\b)
-匹配多個未以字符串開頭的大寫字母的第一種選擇,單詞邊界或另一個大寫字母,然后是小寫字母或單詞邊界, (?<!^\\p{Lu}*|\\b)\\p{Lu}(?=\\p{Ll}|(?<!\\p{Lu}*)\\b)
-與a匹配的第二種選擇單個大寫字母,其開頭不能是字符串的開頭,緊隨其后的是可選的大寫字母(或單詞邊界),然后是小寫字母或不包含可選的大寫字母的單詞邊界。 您是否需要使用Regex? 老實說,我完全不會使用Regex。 它們很難調試並且不易讀。
我將使用一個小的,可重用的,易於測試的擴展方法:
class Program
{
static void Main(string[] args)
{
string[] inputs = new[]
{
"ABCTest",
"HelloWorld",
"testTest$Test",
"aaҚbb"
};
var output = inputs.Select(x => x.SplitWithSpaces(CultureInfo.CurrentUICulture));
foreach (string x in output)
{
Console.WriteLine(x);
}
Console.Read();
}
}
public static class StringExtensions
{
public static bool IsLowerCase(this TextInfo textInfo, char input)
{
return textInfo.ToLower(input) == input;
}
public static string SplitWithSpaces(this string input, CultureInfo culture = null)
{
if (culture == null)
{
culture = CultureInfo.InvariantCulture;
}
TextInfo textInfo = culture.TextInfo;
StringBuilder sb = new StringBuilder(input);
for (int i = 1; i < sb.Length; i++)
{
int previous = i - 1;
if (textInfo.IsLowerCase(sb[previous]))
{
int insertLocation = previous - 1;
if (insertLocation > 0)
{
sb.Insert(insertLocation, ' ');
}
while (i < sb.Length && textInfo.IsLowerCase(sb[i]))
{
i++;
}
}
}
return sb.ToString();
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.