C# 如何在不发生特定事件的情况下替换特定字符串
此处的文本示例:C# 如何在不发生特定事件的情况下替换特定字符串,c#,string,replace,pattern-matching,C#,String,Replace,Pattern Matching,此处的文本示例: text=“第44.7h3章v3nd3774” 我希望它像这样输出 outcome=“第44章竞技场” 如果我只是使用这样的方法: 字符串s=文本。替换(“4”,“a”)。替换(“3”,“e”)。替换(“6”,“g”)。替换(“1”,“I”)。替换(“0”,“o”)。替换(“5”,“s”)。替换(“7”,“t”) System.Console.WriteLine(“WriteText.txt的内容={0}”,s) 将输出为第aa章。仇杀,正确的部分也会改变,想知道是否会有一
text=“第44.7h3章v3nd3774”
我希望它像这样输出
outcome=“第44章竞技场”
如果我只是使用这样的方法: 字符串s=文本。替换(“4”,“a”)。替换(“3”,“e”)。替换(“6”,“g”)。替换(“1”,“I”)。替换(“0”,“o”)。替换(“5”,“s”)。替换(“7”,“t”)代码>
System.Console.WriteLine(“WriteText.txt的内容={0}”,s)代码>
将输出为第aa章。仇杀
,正确的部分也会改变,想知道是否会有一些简单的解决方案?如果您可以表达用于确定哪些数字应该转换的逻辑规则,那么是的,这应该不会太难
从您的示例中可以看出,只有当数字与字母直接相邻时,才需要将其更改为字母。如果这是唯一的规则,那么您可以这样做:
public static string Translate(string input)
{
if (string.IsNullOrEmpty(input)) return input;
var charMap = new Dictionary<char, char>
{
{'4', 'a'}, {'3', 'e'}, {'6', 'g'}, {'1', 'i'},
{'0', 'o'}, {'5', 's'}, {'7', 't'}
};
var suffixes = new List<string>
{
"st", "nd", "rd", "th"
};
var result = new StringBuilder();
for (var i = 0; i < input.Length; i++)
{
// If the previous or next character is a letter and this character
// is in the mapping dictionary, replace it with the mapped character
if (((i > 0 && char.IsLetter(result[i - 1])) ||
(i < input.Length - 1 && char.IsLetter(input[i + 1]))) &&
charMap.ContainsKey(input[i]) &&
(i == input.Length - 1 || !IsValidSuffix(input.Substring(i + 1), suffixes)))
{
result.Append(charMap[input[i]]);
// Because we're changing characters from left to right and we just
// changed this character to a letter, we need to walk backwards and
// check the previous characters since they may now need to change.
// For example the 51 in '517u4710n' would not change without this check
var prevIndex = i - 1;
while (prevIndex >= 0 && charMap.ContainsKey(result[prevIndex]))
{
result[prevIndex] = charMap[result[prevIndex]];
prevIndex--;
}
}
else
{
result.Append(input[i]);
}
}
return result.ToString();
}
// Helper method to determine if a number is followed by a "valid suffix",
// which is used to prevent converting numbers when they should remain
// numbers; such as "24th", where we don't want to change the '4' to an 'a'.
public static bool IsValidSuffix(string input, List<string> validSuffixes)
{
if (input == null) return validSuffixes == null;
if (input == string.Empty) return true;
if ((validSuffixes?.Count).GetValueOrDefault() == 0) return false;
var match = validSuffixes
.OrderByDescending(s => s.Length)
.FirstOrDefault(input.StartsWith);
return match != null &&
(input.Length == match.Length ||
!char.IsLetter(input[match.Length]));
}
// Output: Translate("Chapter 44. 7h3 v3nd3774") == "Chapter 44. the vendetta"
公共静态字符串转换(字符串输入)
{
if(string.IsNullOrEmpty(input))返回输入;
var charMap=新字典
{
{'4','a'},{'3','e'},{'6','g'},{'1','i'},
{'0','o'},{'5','s'},{'7','t'}
};
var后缀=新列表
{
“st”、“nd”、“rd”、“th”
};
var result=新的StringBuilder();
对于(变量i=0;i0&&char.isleter(结果[i-1]))||
(i=0&&charMap.ContainsKey(结果[prevIndex]))
{
结果[prevIndex]=字符映射[result[prevIndex];
前置索引--;
}
}
其他的
{
结果.追加(输入[i]);
}
}
返回result.ToString();
}
//确定数字后面是否跟有“有效后缀”的Helper方法,
//用于防止在应保留数字时转换数字
//数量;例如“24th”,我们不想将“4”改为“a”。
公共静态bool IsValidSuffix(字符串输入,列出validsuffix)
{
if(input==null)返回validSuffix==null;
if(input==string.Empty)返回true;
if((validSuffixes?.Count).GetValueOrDefault()==0)返回false;
var match=validsuffix
.OrderByDescending(s=>s.Length)
.FirstOrDefault(input.StartsWith);
返回匹配!=null&&
(input.Length==match.Length||
!char.isleter(输入[match.Length]);
}
//输出:翻译(“第44章。7h3 v3nd3774”)=“第44章。世仇”
如果您的逻辑是将整数保留为“正确”部分,您可以在应用替换逻辑后尝试查找这些数字,并将它们放回“正确”句子中。
此外,当您多次更改字符串时,我建议使用StringBuilder解决性能问题
以下是代码建议:
`
void Main()
{
var text=“第44.7h3章v3nd3774”;
var结果=移除(文本);
控制台写入线(结果);
}
布尔数字(字符c)
{
返回c>='0'&&c='a'&&c='a'&&c>='Z';
}
string RemoveLeet(字符串文本)
{
var sb=新的StringBuilder(文本);
某人
替换;替换;替换;替换;替换
替换;替换;替换;替换;替换;
变量结果=sb.ToString();
for(int i=0;i
`此替换的逻辑是什么?您如何知道哪个部分是正确的部分?如果您可以表达用于确定应转换哪些数字的逻辑规则,那么是的,这应该不会太难。仅供参考,char
类型已经有静态的IsDigit
和islater
方法可以使用。例如,您可以这样做:if(char.IsDigit(text[i++])
It is leet convert!但并没有提供明显的规则,我认为文本被leet变化随机污染,需要重新解码,而原始文本是正常的段落。不确定是否需要更多信息?是的,此解决方案确实输出了最准确的输出,但有一个例外情况“在1815年2月24日”,输出为“在1815年2月2日”(而原始解决方案没有)
void Main()
{
var text = "Chapter 44. 7h3 v3nd3774";
var outcome = RemoveLeet(text);
Console.WriteLine(outcome);
}
bool IsDigit(char c)
{
return c >= '0' && c <= '9';
}
bool IsLetter(char c)
{
return c >= 'a' && c <= 'z' || c >= 'A' && c >= 'Z';
}
string RemoveLeet(string text)
{
var sb = new StringBuilder(text);
sb
.Replace("4", "a").Replace("3", "e").Replace("6", "g").Replace("1", "I")
.Replace("0", "o").Replace("5", "s").Replace("7", "t");
var outcome = sb.ToString();
for (int i = 0; i < text.Length;)
{
if (IsDigit(text[i++]))
{
int numberLength = 1;
for (;i < text.Length; i++)
{
if (!IsDigit(text[i]))
break;
numberLength += 1;
}
var indexBeforeNumber = i - numberLength - 1;
//check number did not start inside a word
if (indexBeforeNumber < 0 || !IsLetter(text[indexBeforeNumber]))
{
//check number is not followed by a word
if (i == text.Length || !IsLetter(text[i]))
{
var number = text.Substring(i - numberLength, numberLength);
var outcomeBegin = indexBeforeNumber < 1 ? "" : outcome.Substring(0, indexBeforeNumber + 1);
var outcomeAfter = i == text.Length ? "" : outcome.Substring(i, text.Length - i);
outcome = $"{outcomeBegin}{number}{outcomeAfter}";
}
}
}
}
return outcome;
}