我有一组我需要用来替换的句子,例如:
abc => cde
ab df => de
...
我有一个文本可以进行更改。 但是我无法预先知道所述文本的情况。 所以,例如,如果我有:
A bgt abc hyi. Abc Ab df h
我必须替换并获得:
A bgt cde nyi. Cde De h
或尽可能接近,即保留案例
编辑:由于我对这一点感到很困惑,我会尝试澄清一下:
我问的是一种在更换后保留帽子的方法,我不认为它通过了很好(没有很好地解释了什么需要)所以我会用真实的单词给出一个更现实的例子。
把它想象成一个gossary,用它们的正义代替表达式,所以如果我映射:
didn't achieve success => failled miserably
然后我得到了句子的输入:
As he didn't achieve success, he was fired
我会得到
As he failled miserably, he was fired
但是如果没有资本化,那么如果实现或成功资本化,那么就会失败,所以如果有任何超过1个字母的资本化,那将是悲惨的,所以它会是对手
我的主要可能性是(我真正想要考虑的事情)
如果我可以处理那些已经可以接受的三个 - 我认为这是更容易的 - 当然,如果可以使用,更深入的解决方案会更好
有什么想法吗?
答案 0 :(得分:4)
不确定这会有多好用,但这就是我想出来的:
string input = "A bgt abc hyi. Abc Ab df h";
Dictionary<string, string> map = new Dictionary<string, string>();
map.Add("abc", "cde");
map.Add("ab df", "de");
string temp = input;
foreach (var entry in map)
{
string key = entry.Key;
string value = entry.Value;
temp = Regex.Replace(temp, key, match =>
{
bool isUpper = char.IsUpper(match.Value[0]);
char[] result = value.ToCharArray();
result[0] = isUpper
? char.ToUpper(result[0])
: char.ToLower(result[0]);
return new string(result);
}, RegexOptions.IgnoreCase);
}
label1.Text = temp; // output is A bgt cde hyi. Cde De h
修改强> 阅读修改过的问题之后,这是我的修改后的代码(事实证明是与@ Sephallia的代码类似的步骤..和类似的变量名称lol)
现在代码有点复杂......但我认为没关系
string input =
@"As he didn't achieve success, he was fired.
As he DIDN'T ACHIEVE SUCCESS, he was fired.
As he Didn't Achieve Success, he was fired.
As he Didn't achieve success, he was fired.";
Dictionary<string, string> map = new Dictionary<string, string>();
map.Add("didn't achieve success", "failed miserably");
string temp = input;
foreach (var entry in map)
{
string key = entry.Key;
string value = entry.Value;
temp = Regex.Replace(temp, key, match =>
{
bool isFirstUpper, isEachUpper, isAllUpper;
string sentence = match.Value;
char[] sentenceArray = sentence.ToCharArray();
string[] words = sentence.Split(' ');
isFirstUpper = char.IsUpper(sentenceArray[0]);
isEachUpper = words.All(w => char.IsUpper(w[0]) || !char.IsLetter(w[0]));
isAllUpper = sentenceArray.All(c => char.IsUpper(c) || !char.IsLetter(c));
if (isAllUpper)
return value.ToUpper();
if (isEachUpper)
{
// capitalize first of each word... use regex again :P
string capitalized = Regex.Replace(value, @"\b\w", charMatch => charMatch.Value.ToUpper());
return capitalized;
}
char[] result = value.ToCharArray();
result[0] = isFirstUpper
? char.ToUpper(result[0])
: char.ToLower(result[0]);
return new string(result);
}, RegexOptions.IgnoreCase);
}
textBox1.Text = temp;
/* output is :
As he failed miserably, he was fired.
As he FAILED MISERABLY, he was fired.
As he Failed Miserably, he was fired.
As he Failed miserably, he was fired.
*/
答案 1 :(得分:3)
您可以使用String.IndexOf并指定StringComparison.CurrentCultureIgnoreCase
来查找匹配项。此时,逐字符替换字符可以进行交换。可以通过使用Char.IsUpper
检查源字符,然后根据需要在目标上使用Char.ToUpper或Char.ToLower来处理大小写。
答案 2 :(得分:2)
您可以将String作为字符数组循环并使用Char.IsUpper(char parameter)
可能不是最有效或最壮观的做事方式,但它很简单,而且有效。
旁注:我不确定你是如何转换角色的,但是如果你说,将字符向下移动字母表(当你想要转换它们时)一定量,让我们说你是移动3.所以a - &gt; d和E - &gt; G或类似的东西,然后你可以从字符中获取ASCII值,添加3(如果你想转换它),然后从ASCII值中获取字符。如上所述here。你必须做检查,以确保你从字母表的末尾循环回来。 (或者从头开始,如果你向左移动)。
编辑#1 :(继续保持上述内容)
真的很大的代码块......抱歉!这是我能看到你做的最好的方式。希望有人可能会提出一种更优雅的方式。如果您需要澄清,请发表评论或其他任何内容!
// (to be clear) This is Elias' (original) code modified.
static void Main(string[] args)
{
string input = "As he DIDN'T ACHIEVE Success, he was fired";
Dictionary<string, string> map = new Dictionary<string, string>();
map.Add("didn't achieve success", "failed miserably");
string temp = input;
foreach (var entry in map)
{
string key = entry.Key;
string value = entry.Value;
temp = Regex.Replace(temp, key, match =>
{
string[] matchSplit = match.Value.Split(' ');
string[] valueSplit = value.Split(' ');
// Set the number of words to the lower one.
// If they're the same, it doesn't matter.
int numWords = (matchSplit.Length <= valueSplit.Length)
? matchSplit.Length
: valueSplit.Length;
// only first letter of first word capitalized
// only first letter of every word capitalized
// all letters capitalized
char[] result = value.ToCharArray(); ;
for (int i = 0; i < numWords; i++)
{
if (char.IsUpper(matchSplit[i][0]))
{
bool allIsUpper = true;
int c = 1;
while (allIsUpper && c < matchSplit[i].Length)
{
if (!char.IsUpper(matchSplit[i][c]) && char.IsLetter(matchSplit[i][c]))
{
allIsUpper = false;
}
c++;
}
// if all the letters of the current word are true, allIsUpper will be true.
int arrayPosition = ArrayPosition(i, valueSplit);
Console.WriteLine(arrayPosition);
if (allIsUpper)
{
for (int j = 0; j < valueSplit[i].Length; j++)
{
result[j + arrayPosition] = char.ToUpper(result[j + arrayPosition]);
}
}
else
{
// The first letter.
result[arrayPosition] = char.ToUpper(result[arrayPosition]);
}
}
}
return new string(result);
}, RegexOptions.IgnoreCase);
}
Console.WriteLine(temp);
}
public static int ArrayPosition(int i, string[] valueSplit)
{
if (i > 0)
{
return valueSplit[i-1].Length + 1 + ArrayPosition(i - 1, valueSplit);
}
else
{
return 0;
}
return 0;
}
答案 3 :(得分:0)
一次更换一个字符并使用
if(currentChar.ToString() == currentChar.ToUpper(currentChar).ToString())
{
//replace with upper case variant
}
答案 4 :(得分:0)
这几乎是里德所说的。唯一的诀窍是,当Find
和Replace
字符串长度不同时,我不确定应该怎么做。所以我选择最小长度并使用它...
static string ReplaceCaseInsensitive(string Text, string Find, string Replace)
{
char[] NewText = Text.ToCharArray();
int ReplaceLength = Math.Min(Find.Length, Replace.Length);
int LastIndex = -1;
while (true)
{
LastIndex = Text.IndexOf(Find, LastIndex + 1, StringComparison.CurrentCultureIgnoreCase);
if (LastIndex == -1)
{
break;
}
else
{
for (int i = 0; i < ReplaceLength; i++)
{
if (char.IsUpper(Text[i + LastIndex]))
NewText[i + LastIndex] = char.ToUpper(Replace[i]);
else
NewText[i + LastIndex] = char.ToLower(Replace[i]);
}
}
}
return new string(NewText);
}