您好我想将一个正确的单词转换为标题中的单词。例如:
NumberOfLoyalHonestWomen
将成为
忠诚的女性人数
它基本上是一种结合反射的方式,可以在自动生成屏幕输入时将字段/属性名称转换为穷人的标签。
这就是我得到的。有更好或更清洁的方式吗? Dot Net Fiddle
using System;
using System.Text.RegularExpressions;
using System.Linq;
public class Program
{
public static void Main()
{
string testString = "ATCPConnection";
Console.WriteLine(testString.ToSentence());
}
}
public static class StringExtensions
{
public static string ToSentence(this string Source)
{
return Regex.Replace(string.Concat(from Char c
in Source.ToCharArray()
select Char.IsUpper(c) ? " " + c : c.ToString()).Trim(),
"(?<AcronymLetter>[A-Z]) (?=[A-Z](?![a-z]))",
"${AcronymLetter}");
}
}
旁注:由于我希望保持首字母缩略词的完整性,因此很复杂,因此Regex.Replace
。例如:
MGTOWSaysThereAreMoreUnicorns
将成为
MGTOW表示还有更多的独角兽
答案 0 :(得分:5)
这是另一种方法:
因此:
C:\Program Files\mingw64>g++ -std=c++11 pracrise.cpp -lpthread
pracrise.cpp: In function 'int main()':
pracrise.cpp:25:15: error: 'quick_exit' was not declared in this scope
quick_exit(0);
^
更新:上面的两个正则表达式可以组合成一行:
public static string ToSentence(this string Source)
{
Source = Regex.Replace(Source, "((?<!^)[A-Z][a-z])", " $1");
Source = Regex.Replace(Source, "([a-z])([A-Z])", "$1 $2");
return Source;
}
答案 1 :(得分:3)
这个实现怎么样?
仅供参考:System.Runtime.CompilerServices.ExtensionAttribute
不能在C#中使用
(它可以在VB.NET中使用。)
使用this
关键字标记方法的第一个参数。
public static string ToSentence(this string value)
{
char[] characters = value.ToCharArray();
// Determine where groups start
List<int> groupStartIndexes =
characters
.Select((character, index) =>
new
{
Character = character,
Index = index
}
)
.Where(obj => Char.IsUpper(obj.Character))
.Select(obj => obj.Index)
.ToList();
// if there is no upper case letter or
// if value does not start with an upper case letter
if (!groupStartIndexes.Contains(0))
{
groupStartIndexes.Insert(0, 0);
}
// To make our life easier
groupStartIndexes.Add(value.Length);
var groups = new List<string>();
// Split value into groups
for (int index = 0; index < groupStartIndexes.Count - 1; index++)
{
int currentGroupStartIndex = groupStartIndexes[index];
int nextGroupStartIndex = groupStartIndexes[index + 1];
string currentGroup =
value
.Substring(
currentGroupStartIndex,
nextGroupStartIndex - currentGroupStartIndex
);
groups.Add(currentGroup);
}
var sb = new StringBuilder(groups[0]);
// Build the final string
for (int currentGroupIndex = 1; currentGroupIndex < groups.Count; currentGroupIndex++)
{
string previousGroup = groups[currentGroupIndex - 1];
string currentGroup = groups[currentGroupIndex];
if (previousGroup.Length > 1 || currentGroup.Length > 1)
{
sb.Append(" ");
}
sb.Append(groups[currentGroupIndex]);
}
return sb.ToString();
}
答案 2 :(得分:2)
这似乎是一个有趣的话题。这是我的尝试。
public static string ToSentence(this string src) {
var retVal = "";
if (src.Length > 0) {
List<string> wordCollection = new List<string>();
int startIndex = 0;
char[] letters = src.ToCharArray();
//Skip the First Letter
var length = letters.Length;
for (int i = 1; i < length; i++) {
if (char.IsUpper(letters[i])) {
//Check for acronyms
if (char.IsUpper(letters[i - 1])
&& (
i == length - 1 ||
((i + 1) < length && (char.IsUpper(letters[i + 1]) || char.IsNumber(letters[i + 1])))
)
)
continue;
//Grab Eeverything before Current Index
var temp = new String(letters, startIndex, i - startIndex);
wordCollection.Add(temp.Trim());
startIndex = i;
}
}
wordCollection.Add(new String(letters, startIndex, letters.Length - startIndex));
retVal = String.Join(" ", wordCollection);
}
return retVal;
}
以下测试全部通过
public class TestCases {
[DataDrivenTestMethod]
[DataRow("NumberOfLoyalHonestWomen", "Number Of Loyal Honest Women")]
[DataRow("MGTOWSaysThereAreMoreUnicorns", "MGTOW Says There Are More Unicorns")]
[DataRow("MGTOW1SaysThereAreMoreUnicorns", "MGTOW1 Says There Are More Unicorns")]
[DataRow("MGTOWSaysThereAreMOREUnicorns", "MGTOW Says There Are MORE Unicorns")]
[DataRow("MGTOWSaysThereAREMoreUNICORNS", "MGTOW Says There ARE More UNICORNS")]
public void ConvertToTitleCase(string stringUnderTest, string expected) {
var actual = stringUnderTest.ToSentence();
Assert.AreEqual(expected, actual);
}
}
答案 3 :(得分:1)
这种方法类似于@ Gabor,有一些保障和优化。虽然不可能像@ MichaelLiunot的正则表达式解决方案那样紧凑,但它应该快得多。我已经针对目前给出的所有例子进行了测试。
public static string ToSentence(this string value)
{
if (value == null) return value;
int length = value.Length;
if (length <= 1) return value;
var sb = new StringBuilder(value[0].ToString(), length);
char currentChar;
for (int ubound = length - 2, i = 1; i <= ubound; ++i)
{
currentChar = value[i];
if (Char.IsUpper(currentChar) && (Char.IsLower(value[i - 1]) || Char.IsLower(value[i + 1])))
sb.Append(' ');
sb.Append(currentChar);
}
currentChar = value[length - 1];
if (Char.IsUpper(currentChar) && Char.IsLower(value[length - 2]))
sb.Append(' ');
sb.Append(currentChar);
return sb.ToString();
}