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());
}