C# 删除/替换特殊字符的低复杂度算法
我想替换上载到我的应用程序的文件名中的一些无效字符 我在互联网上搜索了一些东西,找到了一些复杂的算法,这里有一个:C# 删除/替换特殊字符的低复杂度算法,c#,complexity-theory,C#,Complexity Theory,我想替换上载到我的应用程序的文件名中的一些无效字符 我在互联网上搜索了一些东西,找到了一些复杂的算法,这里有一个: public static string RemoverAcentuacao(string palavra) { string palavraSemAcento = null; string caracterComAcento = "áàãâäéèêëíìîïóòõôöúùûüçáàãâÄéèêëíìî
public static string RemoverAcentuacao(string palavra)
{
string palavraSemAcento = null;
string caracterComAcento = "áàãâäéèêëíìîïóòõôöúùûüçáàãâÄéèêëíìîïóòõÖôúùûÜç, ?&:/!;ºª%‘’()\"”“";
string caracterSemAcento = "aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC___________________";
if (!String.IsNullOrEmpty(palavra))
{
for (int i = 0; i < palavra.Length; i++)
{
if (caracterComAcento.IndexOf(Convert.ToChar(palavra.Substring(i, 1))) >= 0)
{
int car = caracterComAcento.IndexOf(Convert.ToChar(palavra.Substring(i, 1)));
palavraSemAcento += caracterSemAcento.Substring(car, 1);
}
else
{
palavraSemAcento += palavra.Substring(i, 1);
}
}
string[] cEspeciais = { "#39", "---", "--", "'", "#", "\r\n", "\n", "\r" };
for (int q = 0; q < cEspeciais.Length; q++)
{
palavraSemAcento = palavraSemAcento.Replace(cEspeciais[q], "-");
}
for (int x = (cEspeciais.Length - 1); x > -1; x--)
{
palavraSemAcento = palavraSemAcento.Replace(cEspeciais[x], "-");
}
palavraSemAcento = palavraSemAcento.Replace("+", "-").Replace(Environment.NewLine, "").TrimStart('-').TrimEnd('-').Replace("<i>", "-").Replace("<-i>", "-").Replace("<br>", "").Replace("--", "-");
}
else
{
palavraSemAcento = "indefinido";
}
return palavraSemAcento.ToLower();
}
public静态字符串删除工具acentuacao(字符串palavra)
{
字符串palavraSemAcento=null;
字符串caracterComAcento=“áãèèèèèèèèèèèèèèèèèèèèèèèèèèè;
字符串caractersemento=“aaaaa eeeeiiioouuucaaaaaeeeiioouuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu;
如果(!String.IsNullOrEmpty(palavra))
{
for(int i=0;i=0)
{
int car=caracterComAcento.IndexOf(Convert.ToChar(palavra.Substring(i,1));
palavraSemAcento+=CaractersCento.子字符串(car,1);
}
其他的
{
palavraSemAcento+=palavra.子串(i,1);
}
}
字符串[]cEspeciais={“#39”、“--”、“--”、“#”、“\r\n”、“\n”、“\r”};
for(int q=0;q-1;x--)
{
palavraSemAcento=palavraSemAcento.替换(cEspeciais[x],“-”;
}
palavraSemAcento=palavraSemAcento.Replace(“+”,“-”).Replace(Environment.NewLine,”).TrimStart(“-”).trimsend(“-”).Replace(“,”).Replace(“
”,”).Replace(“,”).Replace(“-”,”).Replace(“-”,“-”);
}
其他的
{
palavraSemAcento=“indefinedo”;
}
返回palavraSemAcento.ToLower();
}
有一种方法可以用不太复杂的算法来实现吗?
我认为这个算法非常复杂,不太复杂,但我不能从不同的角度思考。这是我最近使用的一个非常简单的方法 我希望它能满足您的要求。老实说,由于变量声明的语言,代码有点难读
List<char> InvalidCharacters = new List<char>() { 'a','b','c' };
static string StripInvalidCharactersFromField(string field)
{
for (int i = 0; i < field.Length; i++)
{
string s = new string(new char[] { field[i] });
if (InvalidCharacters.Contains(s))
{
field = field.Remove(i, 1);
i--;
}
}
return field;
}
List InvalidCharacters=new List(){'a','b','c'};
静态字符串StripInvalidCharactersFromField(字符串字段)
{
for(int i=0;i
使用正则表达式的解决方案:
string ReplaceSpecial(string input, string replace, char replacewith)
{
char[] back = input.ToCharArray();
var matches = Regex.Matches(String.Format("[{0}]", replace), input);
foreach (var i in matches)
back[i.Index] = replacewith;
return new string(back);
}
使用字符串的简单解决方案。替换:
string ReplaceSpecial(string input, char[] replace, char replacewith)
{
string back = input;
foreach (char i in replace)
back.Replace(i, replacewith);
return back;
}
我想替换文件名中的一些无效字符
如果这真的是你想要的,那么很容易
string ToLegalFileName(string s)
{
var invalidChars = new HashSet<char>(Path.GetInvalidFileNameChars());
return String.Join("", s.Select(c => invalidChars.Contains(c) ? '_' : c));
}
这是第三个版本,它将重音字符+其他字符替换为“\ux”
string RemoverAcentuacao2(string s)
{
return String.Join("",
s.Normalize(NormalizationForm.FormD)
.Where(c => char.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
.Select(c => char.IsLetterOrDigit(c) ? c : '_')
.Select(c => (int)c < 128 ? c : '_'));
}
字符串移除器ACENTUACAO2(字符串s)
{
返回字符串。Join(“,
s、 规范化(NormalizationForm.FormD)
.Where(c=>char.getUnicodeCegory(c)!=UnicodeCegory.NonSpacingMark)
.Select(c=>char.IsleterOrdigit(c)?c:''u')
.选择(c=>(int)c<128?c:''u');
}
如果它能工作,你为什么要关心它有多复杂?你可以尝试使用编译后的正则表达式。这段代码所做的不仅仅是删除具有设置字符列表的字符的所有实例……如果你需要更复杂的逻辑,那么在这件事上就没有太多选择。如果你只需要删除某些字符的所有实例,这是一个很好的选择比那段代码容易得多。如果它能工作,而你只是想要一个更好的解决方案,你应该把它发布在上,而不是这里。你是在谈论可读性,还是关于运行时的复杂性?事实上,你使用字符串连接使这比它应该的要慢得多。他不想删除它们,他想替换它们(尽管标题).@Servy和往常一样做出了精彩的贡献。你在这里真的很开心。@Servy我担心你完全没有抓住重点。他要求一个“不太复杂”的算法,而“性能”一词在他的帖子中出现了整整0次。我敢打赌,根据“复杂”的标准,这可能会被认为比他原来的要简单得多。此外,对于我的帖子中的低效,至少给出一点解释。你没有让我或任何人意识到一件事。知识的扩展也是如此,即使传递得很严厉。不仅仅是……令人不快。你的答案在哪里?@Michael OP中的代码做得更多。这个代码示例没有表现出同样的乐趣功能性,因此比较代码的数量或复杂度并不是真正相关的;它们做的不是同一件事。如果你对我所指的内容感到好奇,你可以简单地问一下。有许多基本问题。Remove
将对除一个字符外的所有字符进行复制。t这将导致大量冗余的数据复制。List
也无法有效搜索,您应该使用哈希集。这应该可以让您开始了。@Servy谢谢。我受到启发,了解了更多关于字符串及其不变性的知识(我认为这是导致数据复制过多的原因).我喜欢你以前的版本;-)事实上,我使用了你现在提出的类似形式-它使文件名正确,但更改了一点。只需将重音字母转换为非重音字母可能会更平滑,更符合这里的问题。找到一种简单的更改重音的方法会很酷。
string RemoverAcentuacao2(string s)
{
return String.Join("",
s.Normalize(NormalizationForm.FormD)
.Where(c => char.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
.Select(c => char.IsLetterOrDigit(c) ? c : '_')
.Select(c => (int)c < 128 ? c : '_'));
}
static string RemoverAcentuacao(string s)
{
string caracterComAcento = "áàãâäéèêëíìîïóòõôöúùûüçáàãâÄéèêëíìîïóòõÖôúùûÜç, ?&:/!;ºª%‘’()\"”“";
string caracterSemAcento = "aaaaaeeeeiiiiooooouuuucAAAAAEEEEIIIIOOOOOUUUUC___________________";
return new String(s.Select(c =>
{
int i = caracterComAcento.IndexOf(c);
return (i == -1) ? c : caracterSemAcento[i];
}).ToArray());
}