将文本转换为小写,但对于大写的单词保留大写
本文关键字:于大写 单词 保留 转换 文本 | 更新日期: 2023-09-27 18:10:45
我在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();
}
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));
}
这将把句子开头的任何小写单词转换为大写单词。例如:
嗨。我是Matteo,在IP工作。
将被转换为
嗨。我是Matteo,在IP工作。
相似的,
嗨。我是Matteo,在IP工作。请把你的问题直接问我。请随时给我发邮件或打电话。
将转换为:
嗨。我是Matteo,在IP工作。请把你的问题直接问我。请随时给我发邮件或打电话。
在您的问题中处理这种特定字符串操作的最佳方法是使用Regex类。我建议看看MSDN关于如何在。net中使用正则表达式的最小文档。如果你不熟悉如何使用正则表达式,你可以通过你喜欢的搜索引擎找到很多帮助。
我将用最后一个例子来说明。为了与MSDN提供的示例相吻合(说明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。
- |是交替/或操作数,所以在它之前或之后的逻辑都适用。
- (?<='W{2})是正向向后查找,它在以下集合之前搜索恰好两个非单词字符…
- …这是最后一个[a-z],它搜索小写字母a到z。
我爱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);
}
}
遵循下面的代码
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;
}