C# 将适当大小写转换为标题大小写中的句子(与句子大小写相反)
你好,我想把一个适当大小写的单词转换成一个标题大小写的句子。例如:C# 将适当大小写转换为标题大小写中的句子(与句子大小写相反),c#,C#,你好,我想把一个适当大小写的单词转换成一个标题大小写的句子。例如: 忠诚女性的数量将成为 忠诚诚实的妇女人数 这基本上是一种与反射相结合的方式,在自动生成屏幕输入时,将字段/属性名称转换为穷人的标签 这是我得到的。有更好或更干净的方法吗? 使用系统; 使用System.Text.RegularExpressions; 使用System.Linq; 公共课程 { 公共静态void Main() { string testString=“ATCPConnection”; WriteLine(tes
忠诚女性的数量将成为
忠诚诚实的妇女人数
这基本上是一种与反射相结合的方式,在自动生成屏幕输入时,将字段/属性名称转换为穷人的标签
这是我得到的。有更好或更干净的方法吗?
使用系统;
使用System.Text.RegularExpressions;
使用System.Linq;
公共课程
{
公共静态void Main()
{
string testString=“ATCPConnection”;
WriteLine(testString.ToSentence());
}
}
公共静态类扩展
{
公共静态字符串ToSentence(此字符串源)
{
返回Regex.Replace(string.Concat)(来自Char c
在Source.ToCharArray()中
选择Char.IsUpper(c)?“”+c:c.ToString()).Trim(),
“(?[A-Z])(?=[A-Z](?![A-Z])”,
“${首字母缩写}”);
}
}
旁注:由于我希望保持首字母缩略词的完整性,所以使用了Regex.Replace
,这使问题变得复杂起来。例如:
mgtow说,Rearemoreunicorns
将成为
MGTOW说还有更多的独角兽
这个实现怎么样
仅供参考: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();
}
publicstaticstringtocentence(此字符串值)
{
char[]characters=value.ToCharArray();
//确定组的起始位置
列表组StartIndex=
人物
.选择((字符、索引)=>
新的
{
字符=字符,
索引=索引
}
)
.Where(obj=>Char.IsUpper(obj.Character))
.选择(对象=>对象索引)
.ToList();
//如果没有大写字母或
//如果值不以大写字母开头
如果(!GroupStartIndex.Contains(0))
{
groupStartIndexes.Insert(0,0);
}
//让我们的生活更轻松
groupStartIndexes.Add(value.Length);
变量组=新列表();
//将值拆分为组
对于(int index=0;index1 | |当前group.Length>1)
{
某人加上(“”);
}
sb.追加(组[currentGroupIndex]);
}
使某人返回字符串();
}
还有另一种方法:
在每个大写字母前插入一个空格,空格后面紧跟着一个小写字母(除非出现在字符串开头)。这会在指定的单词前添加空格
然后在每个大写字母前插入一个空格,该空格前面紧跟着一个小写字母。这会在首字母缩略词前添加空格
因此:
publicstaticstringtosentence(此字符串源)
{
Source=Regex.Replace(Source,“(?这似乎是一个有趣的话题。下面是我的尝试
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;
}
这种方法与@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();
}
publicstaticstringtocentence(此字符串值)
{
if(value==null)返回值;
int length=value.length;
如果(对于您的算法,您希望它如何处理ATCPConnecton
?@MagikM18,ATCP ConnectonYes,但当正确的句子可能是TCP连接时,用户会觉得这很奇怪。我不确定这对您有多重要,但值得思考这是真的,它看起来很奇怪。属性/字段名称开始对于分词A或代词,我会变得一团糟,如果我想在这个算法中有好的标签,我就必须避免这样的属性/字段名。+1你的评论。我喜欢你的实现,因为它避免了使用任何语句。而且,它可能更快。我将把我们的两个算法放在.Net中,并获得时间。谢谢!+1他们的速度一样。看我的小提琴。这个算法不处理嵌入或尾随的首字母缩写词。例如,“mgtowsaytherearemoreunicorns”。ToSentence()
返回“MGTOW说有更多独角兽”
@MichaelLiu我根据你的评论更新了我的答案。@MichaelLiu True.)我更新了我的答案以避免例外。可视化:VisitorsOnFLAGDay
。步骤1:卖旗日访客
。步骤2:卖旗日访客
。完成。令人印象深刻。直接。简单。我使用了此选项;但我刚刚从第二行直接返回,删掉了一行代码。谢谢。我可能会在采访中使用此问题。:-)不错。第一行的另一个可能性是Regex.Replace(源代码,“()([A-Z][A-Z])”,“$1$2”);
投票赞成加强确实有更多的独角兽。罗斯:”mgtowsaytherearemoreunico
public static string ToSentence(this string Source)
{
return Regex.Replace(Source, "(?<!^)[A-Z][a-z]|(?<=[a-z])[A-Z]", " $0");
}
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);
}
}
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();
}