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

时间:2018-06-23 00:47:23

标签: c#

我必须编写一个程序来检查输入是否是回文,并且在此代码中,我需要有一个从字符串中删除所有非字母字符的方法。做这个的最好方式是什么?将输入转换为数组是否更好(现在我以字符串形式进行操作)?我不想为每个单独的字符编写一个循环或将每个字符放入修剪中。装饰也会在中间脱掉吗?

我也不被允许使用正则表达式,可枚举或抛出新异常,因为教授不是后两者的拥护者,而前一个不起作用,只会抛出错误。

我这样做的方式似乎并不是解决此问题的最有效方法。

我的代码在这里:

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

3 个答案:

答案 0 :(得分:1)

简单的LINQ解决方案就像

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

输出:

Example Text

实际上没有什么方法可以避免在某个级别循环遍历字符串。

答案 1 :(得分:0)

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

第二,Phrase.Remove()返回一个删除了1个字符的新字符串-您没有使用该字符串。您可能打算再次将结果分配给Phrase。 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;
}

这有一个缺点,您将需要维护字符数组(存储为字符串)以包括所有非字母字符,虽然目前还没有,但这只是一个开始。

接下来的另一种方法是,在原始字符串上使用循环,利用Char.IsLetter,如Matt的建议所示。这意味着您不需要维护要删除的字符数组。

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

return output;

但是,这仍然会在每次循环迭代中一遍又一遍地创建新的字符串(请记住这是字符串的工作方式),这不是很有效。 最有效的方法是,您可以使用奇妙的StringBuilder类,该类维护一个 mutable 字符/字符串集合,完成后可以组装为单个字符串。值得一读的是,如果您有兴趣以有效的方式进行大量的字符串操作:

StringBuilder builder = new StringBuilder();

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

return builder.ToString();

答案 2 :(得分:0)

就像:

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