将文本转换为小写但保留大写单词的大写

时间:2015-09-01 13:41:30

标签: c# string

我正在c#中搜索一个转换为小写字符串的函数,但将大写字母保持为大写。

"Pippo, pluto. paperino" -> "pippo, pluto. paperino"
"Pippo, PLUTO. paperino" -> "pippo, PLUTO. paperino"

但如果所有单词都是大写,则转换为小写。

"PIPPO, PLUTO. PAPERINO" -> "pippo, pluto. paperino"

我找到了以下解决方案。我也考虑了所有的分隔符。你怎么看?

private static string buildSourceString(string sourceString)
    {
        sourceString += " ";
        var sb = new StringBuilder(sourceString.Length);
        int nOfCharWord = 0;
        int nOfCharLower = 0;
        int nWord = 0;
        int nWordUpper = 0;

        foreach (var c in sourceString)
        {
            if (c == '.' | c == ',' | c == ';' | c == ':' | c == '!' | c == '?' | c == '\n' | c == '\r' || Char.IsWhiteSpace(c))
            {
                if (nOfCharWord > 0)
                    nWord++;
                if (nOfCharWord > 0 && nOfCharWord.Equals(nOfCharLower))
                {

                    for (int i = sb.Length - nOfCharWord; i < sb.Length; i++)
                    {
                        sb[i] = char.ToUpper(sb[i]);
                    }
                    nWordUpper++;
                }
                // reset contatori
                nOfCharWord = 0;
                nOfCharLower = 0;
                sb.Append(c);

            }
            else
            {
                if (c.ToString().Equals(c.ToString().ToUpper()))
                {

                    sb.Append(char.ToLower(c));
                    nOfCharLower++;
                }
                else
                {
                    sb.Append(c);
                }
                nOfCharWord++;
            }
        }
        if (nWord == nWordUpper)
        {
            sb = new StringBuilder(sourceString.Length);
            sb = sb.Append(sourceString.ToLower());
        }

        sb.Remove(sb.Length - 1, 1);
        return sb.ToString();
    }

4 个答案:

答案 0 :(得分:3)

public static bool  IsAllUpper(string input)
{
    for (int i = 0; i < input.Length; i++)
    {
        if (Char.IsLetter(input[i]) && !Char.IsUpper(input[i]))
            return false;
    }
    return true;
}

public static string GetString(String input)
{
    var arr = input.Split(' ');
    var result = "";

    foreach(var item in arr)
    {
        if(IsAllUpper(item))
            result += ' ' + item;
        else
            result += ' ' + item.ToLower();


    }
    return result;
}

public static void Main()
{
    String s1 = "Pippo, pluto. paperino";
    String s2 = "Pippo, PLUTO. paperino";
    String s3 = "PIPPO, PLUTO. PAPERINO";



    Console.WriteLine(GetString(s1));
    Console.WriteLine(GetString(s2));
    Console.WriteLine(GetString(s3));


}

答案 1 :(得分:0)

这会将句子开头的任何小写单词转换成大写单词的开头。例如:

  

喜。我是Matteo,在IP工作。

将转换为

  

您好。我是Matteo,在IP工作。

类似地,

  

喜。我是Matteo,在IP工作。请将您的问题直接发给我。随时发送电子邮件或电话。

将转换为:

  

您好。我是Matteo,在IP工作。请将您的问题直接发给我。随时发送电子邮件或电话。

在您的问题中处理此类特定字符串操作的最佳方法是使用Regex class。我建议查看MSDN关于如何在.NET中使用正则表达式的最小文档。如果您不熟悉如何使用正则表达式,可以通过您最喜欢的搜索引擎找到很多帮助。

我将使用你的上一个例子进行说明。与MSDN here提供的示例相吻合(说明Replace()重载):

class Program
{
    static void Main(string[] args)
    {
        string original = "hi. i'm Matteo and work in IP";
        Console.WriteLine(Regex.Replace(original, @"\A[a-z]|(?<=\W{2})[a-z]", new MatchEvaluator(CapText), RegexOptions.ECMAScript));
        Console.ReadKey();
    }

    static string CapText(Match match)
    {
        string tempStr = match.ToString();
        if (char.IsLower(tempStr[0]))
        {
            return char.ToUpper(tempStr[0]) + tempStr.Substring(1, tempStr.Length - 1);
        }
        return tempStr;
    }
}

这两个关键部分是Regex.Replace中的正则表达式和CapText自定义评估程序方法。

Regex.Replace中的正则表达式可以按如下方式细分:

  • \ A [a-z]在字符串的开头找到一个小写字母a到z。
  • |是交替/ OR操作数,因此在它应用之前或之后都是逻辑。
  • (?&lt; = \ W {2})是正lookbehind,在下面的集合之前搜索正好两个非单词字符...
  • ...这是最后一个[a-z],它搜索小写字母a到z。

答案 2 :(得分:0)

我喜欢TDD :-) 使用您的参数,我会到达此课程:

internal static class ToLowerEx
{
    static readonly Regex Words = new Regex(@"(?'item'\b\w+\b)|(?'item'\b\W+\b)", RegexOptions.ExplicitCapture);
    public static string Get(string text)
    {
        if (!Words.IsMatch(text)) return text;

        var result = new StringBuilder();
        var matches = Words.Matches(text);
        foreach (Match match in matches)
            result.Append(ProcessWord(match.Value));

        return result.ToString();
    }
    private static string ProcessWord(string text)
    {
        return !text.All(char.IsUpper)
            ? text.ToLower()
            : text;
    }
}

万一你感兴趣,这些都是测试:

[TestFixture]
internal class LowerTests
{
    [Test]
    public void Test_asdf_asdf()
    {
        var actual = ToLowerEx.Get("asdf");
        const string expected = "asdf";
        Assert.AreEqual(expected, actual);
    }

    [Test]
    public void Test_Asdf_asdf()
    {
        var actual = ToLowerEx.Get("Asdf");
        const string expected = "asdf";
        Assert.AreEqual(expected, actual);
    }

    [Test]
    public void Test_aSdf_asdf()
    {
        var actual = ToLowerEx.Get("aSdf");
        const string expected = "asdf";
        Assert.AreEqual(expected, actual);
    }

    [Test]
    public void Test_ASDF_ASDF()
    {
        var actual = ToLowerEx.Get("ASDF");
        const string expected = "ASDF";
        Assert.AreEqual(expected, actual);
    }

    [Test]
    public void Test_asdfAndqwer_asdfAandqwer()
    {
        var actual = ToLowerEx.Get("asdf, qwer");
        const string expected = "asdf, qwer";
        Assert.AreEqual(expected, actual);
    }

    [Test]
    public void Test_AsdfAndqWer_asdfAandqwer()
    {
        var actual = ToLowerEx.Get("Asdf, qWer");
        const string expected = "asdf, qwer";
        Assert.AreEqual(expected, actual);
    }

    [Test]
    public void Test_AsdfAndQWER_asdfAandQWER()
    {
        var actual = ToLowerEx.Get("Asdf, QWER");
        const string expected = "asdf, QWER";
        Assert.AreEqual(expected, actual);
    }
}

答案 3 :(得分:0)

按照以下代码

private void button1_Click(object sender, EventArgs e)
{
    String s1 = "Pippo, pluto. paperino";
    String s2 = "Pippo, PLUTO. paperino";
    String s3 = "PIPPO, PLUTO. PAPERINO";

    MessageBox.Show(myStringConverter(s1));
    MessageBox.Show(myStringConverter(s2));
    MessageBox.Show(myStringConverter(s3));
}


public string myStringConverter(string str)
{
    string[] strArray = str.Split(' '); // Word is always seprate by Space.
    string Answer = "";
    for (int i = 0; i < strArray.Length; i++)
    {
        string tempStr = strArray[i];
        var withoutSpecialCharacter = new string(tempStr.Where(c => Char.IsLetterOrDigit(c) || Char.IsWhiteSpace(c)).ToArray());
        if (!withoutSpecialCharacter.All(char.IsUpper))
        {
            Answer += strArray[i].ToLower() + " ";
        }
        else
        {
            Answer += strArray[i] + " ";
        }
    }
    return Answer;
}