C# 如何从字符串中删除所有非字母字符?

C# 如何从字符串中删除所有非字母字符?,c#,C#,我必须编写一个程序来检查输入是否是回文,在这段代码中,我需要有一个从字符串中删除所有非字母字符的方法。最好的方法是什么?现在把输入转换成数组更好吗?我现在把它作为字符串来做?我不想为每个单独的字符写一个循环,也不想把每个字符都修改成trim。修剪中间的东西也会脱落吗? 我也不允许使用regex、enumerable或抛出新异常,因为教授不喜欢后两种方法,而第一种方法不起作用,它只抛出错误 我这样做似乎不是最有效的方法 我的代码在这里: public partial class frmPalin

我必须编写一个程序来检查输入是否是回文,在这段代码中,我需要有一个从字符串中删除所有非字母字符的方法。最好的方法是什么?现在把输入转换成数组更好吗?我现在把它作为字符串来做?我不想为每个单独的字符写一个循环,也不想把每个字符都修改成trim。修剪中间的东西也会脱落吗?

我也不允许使用regex、enumerable或抛出新异常,因为教授不喜欢后两种方法,而第一种方法不起作用,它只抛出错误

我这样做似乎不是最有效的方法

我的代码在这里:

 public partial class frmPalindrome : Form
{
    public frmPalindrome()
    {
        InitializeComponent();
    }

    //allows btnCheck to take in user input in txtEnterWordPhrase and check if it is a palindrome
    private void btnCheck_Click(object sender, EventArgs e)
    {
        try
        {
            if (IsValidData())
            {
                string strPhrase = Convert.ToString(txtEnterWordPhrase.Text);
                string strCleanPhrase = CharacterStrip(strPhrase);

                txtPalindrome.Text = Convert.ToString(IsPalindrome(strCleanPhrase));
            }
        }
        catch (Exception ex) //catches any other exceptions
        {
            MessageBox.Show(ex.Message + "\n\n" + ex.GetType().ToString() + "\n" + ex.StackTrace, "Exception");
        }
    }

    //a method that cuts all the nonalphabetic characters out of txtEnterWordPhrase
    public string CharacterStrip(string Phrase)
    {
        //neither of these seem very efficient
        //Phrase = Phrase.Trim(new Char[] {' ', '&', '*', ',', '-', '_', '/', '\', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',  });

        while (Phrase.IndexOf(" ") >= 0)
        {
           int intIndex = Phrase.IndexOf(" ");
           Phrase.Remove(intIndex, 1);
        }

        return Phrase;
    }

    //checks if the input is a palindrome
    public bool IsPalindrome(string Phrase)
    {
        //not sure how to do this yet
        return true; //have not built this method yet
    }

    //checks that the input is valid
    public bool IsValidData ()
    {
        return IsString(txtEnterWordPhrase, "Enter a Word or Phrase"); //have not built this validation method yet
    }

    //checks that the input in txtEnterWordPhrase is a string
    public bool IsString(TextBox Textbox, string Name)
    {
        decimal Number = 0m;

        if (Decimal.TryParse(Textbox.Text, out Number))
        {
            MessageBox.Show(Name + " must be a word or phrase.", "Entry Error");
            return false;
        }
        else
            return true;

    }

    //allows btnExit to close the program
    private void btnExit_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    //a method that clears txtPalindrome and returns focus to txtEnterWordPhrase
    private void ClearResults(object sender, EventArgs e)
    {
        txtPalindrome.Text = "";
        txtEnterWordPhrase.Focus();
    }
}

一个简单的LINQ解决方案如下

    string exampleString = "123 Example Text 456"; 
    string onlyAlpha = new string(exampleString.Where(c => Char.IsLetter(c)).ToArray());
    Console.WriteLine(onlyAlpha);
输出:

Example Text

在某种程度上,没有任何方法可以避免字符串循环。

首先,示例方法CharacterStrip存在一些问题。Trim将只从字符串的开头和结尾修剪字符,因此一旦遇到数组中不存在的字符,它将假定该字符属于该字符,并停止处理。因此,它不会从字符串中删除所有非字母字符

其次,Phrase.Remove返回一个新字符串,其中删除了1个字符-您没有使用该字符串。您可能想再次将结果分配给短语。C语言中需要学习的一个重要原则是字符串的不变性:一旦你拥有了一个字符串,你就不能改变它,你只能从中创建一个新的字符串,在这种情况下,一个删除了给定索引中字符的字符串。这就是说,即使有了这个修正案,while循环也不会删除非字母字符,它只会删除空格

因此,在担心效率之前,让我们先从一些有用的东西开始,不管这些东西多么不雅观:

public string CharacterStrip(string phrase)
{
    string[] chars = new string[] { " ", "&", "*", ",", "-", "_", "/", "\\", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", };

    foreach (string c in chars)
        phrase = phrase.Replace(c, "");

    return phrase;
}
这样做的缺点是,您需要维护存储为字符串的字符数组,以包含所有非字母字符,目前还没有,但这只是一个开始

另一种方法是,在原始字符串上使用循环,正如Matt的回答所建议的那样。这意味着您不需要维护要删除的字符数组

string output = "";
foreach (char c in phrase)
{
    if (Char.IsLetter(c))
        output = output + c;
}

return output;
但是,这仍然会为每个循环迭代一次又一次地创建新字符串记住,字符串就是这样工作的,这不是很有效。 最有效的是,您可以使用fantastic类,该类维护一个可变的字符/字符串集合,以便在完成后组装成单个字符串。如果您对高效地进行大量字符串操作感兴趣,那么值得一读:

StringBuilder builder = new StringBuilder();

foreach (char c in phrase)
{
    if (Char.IsLetter(c))
        builder.Append(c);
}

return builder.ToString();
简单到:

Regex rgx = new Regex("[^a-zA-Z0-9 -]");
phrase= rgx.Replace(phrase, "");

你到底为什么认为使用修剪是如此低效?我会说它在做什么方面相当有效,但它没有做我认为你期望的事情;它只会从字符串的开头和结尾删除这些字符。@andresairr我不知道它只删除了开头和结尾,我正在寻找可以在整个字符串中使用的字符。如果用户输入test 12 test,我需要将其转换为testtest,请记住在之前阅读帮助asking@user202729你只是想给我看另一个网站吗?这会在文本中间删除任何数字吗?是的。它本质上是遍历整个字符串,只保留传入Char.isleter..NET字符串时返回true的字符,而字符串没有replaceAll方法。那就是Java。请让投票人花点时间解释一下原因好吗?我不允许使用StringBuilder,因为我的教授不喜欢,但你的中间示例非常有趣。你的教授到底不喜欢StringBuilder的什么?我真的不确定,这是一个夏季学期,所以她把课本看完了,当我们讲到这一点时,她说不要用这个,我不喜欢它并继续讲下去