Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将适当大小写转换为标题大小写中的句子(与句子大小写相反)_C# - Fatal编程技术网

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();
    }