如何从字符串[]中删除非字母字符?

时间:2013-07-03 20:36:41

标签: c# regex

这是代码:

StringBuilder sb = new StringBuilder();
Regex rgx = new Regex("[^a-zA-Z0-9 -]");

var words = Regex.Split(textBox1.Text, @"(?=(?<=[^\s])\s+\w)");
for (int i = 0; i < words.Length; i++)
{
    words[i] = rgx.Replace(words[i], "");
}

当我正在执行Regex.Split()时,单词中也包含字符串,其中包含字符:

Daniel>

Hello:

\r\nNew

hello---------------------------

我只需要获得没有所有符号的单词

所以我尝试使用这个循环,但我用语言来结束""有许多地方 还有一些只有------------------------

的地方

我不能在我的代码中使用它作为字符串。

3 个答案:

答案 0 :(得分:10)

您不需要正则表达式来清除非字母。这将删除所有非unicode字母。

public string RemoveNonUnicodeLetters(string input)
{
    StringBuilder sb = new StringBuilder();
    foreach(char c in input)
    {
        if(Char.IsLetter(c))
           sb.Append(c);
    }

    return sb.ToString();
}

或者,如果您只想允许使用拉丁字母,则可以使用此

public string RemoveNonLatinLetters(string input)
{
    StringBuilder sb = new StringBuilder();
    foreach(char c in input)
    {
        if(c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
           sb.Append(c);
    }

    return sb.ToString();
}

基准与正则表达

public static string RemoveNonUnicodeLetters(string input)
{
       StringBuilder sb = new StringBuilder();
       foreach (char c in input)
       {
            if (Char.IsLetter(c))
                sb.Append(c);
       }

            return sb.ToString();
}



static readonly Regex nonUnicodeRx = new Regex("\\P{L}");

public static string RemoveNonUnicodeLetters2(string input)
{
     return nonUnicodeRx.Replace(input, "");
}


static void Main(string[] args)
{

    Stopwatch sw = new Stopwatch();

    StringBuilder sb = new StringBuilder();


    //generate guids as input
    for (int j = 0; j < 1000; j++)
    {
        sb.Append(Guid.NewGuid().ToString());
    }

    string input = sb.ToString();

    sw.Start();

    for (int i = 0; i < 1000; i++)
    {
        RemoveNonUnicodeLetters(input);
    }

    sw.Stop();
    Console.WriteLine("SM: " + sw.ElapsedMilliseconds);

    sw.Restart();
    for (int i = 0; i < 1000; i++)
    {
        RemoveNonUnicodeLetters2(input);
    }

    sw.Stop();
    Console.WriteLine("RX: " + sw.ElapsedMilliseconds);


}

输出(SM =字符串操作,RX =正则表达式)

SM: 581
RX: 9882

SM: 545
RX: 9557

SM: 664
RX: 10196

答案 1 :(得分:2)

keyboardP的解决方案很不错 - 考虑它。但正如我在评论中所说,正则表达式实际上是工作的正确工具,你只是让它变得不必要地复杂化。实际的解决方案是单线:

var result = Regex.Replace(input, "\\P{L}", "");

\P{…} specifies a Unicode character class we do not want to match(与\p{…}相反)。 L字母的Unicode字符类。

当然,将它封装到一个方法中是有意义的,就像keyboardP那样。为了避免重新编译正则表达式,您还应该考虑从实际代码中提取正则表达式(尽管这可能不会对性能产生很大影响):

static readonly Regex nonUnicodeRx = new Regex("\\P{L}");

public static string RemoveNonUnicodeLetters(string input) {
    return nonUnicodeRx.Replace(input, "");
}

答案 2 :(得分:2)

为了帮助Konrad和keyboardP解决他们之间的差异,我使用他们的代码进行了基准测试。事实证明,keyboardP的代码比Konrad的代码快10倍

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Text.RegularExpressions;

    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                string input = "asdf234!@#*advfk234098awfdasdfq9823fna943";
                DateTime start = DateTime.Now;
                for (int i = 0; i < 100000; i++)
                {
                    RemoveNonUnicodeLetters(input);
                }
                Console.WriteLine(DateTime.Now.Subtract(start).TotalSeconds);
                start = DateTime.Now;
                for (int i = 0; i < 100000; i++)
                {
                    RemoveNonUnicodeLetters2(input);
                }
                Console.WriteLine(DateTime.Now.Subtract(start).TotalSeconds);
            }
            public static string RemoveNonUnicodeLetters(string input)
            {
                StringBuilder sb = new StringBuilder();
                foreach (char c in input)
                {
                    if (Char.IsLetter(c))
                        sb.Append(c);
                }

                return sb.ToString();
            }
            public static string RemoveNonUnicodeLetters2(string input)
            {
                var result = Regex.Replace(input, "\\P{L}", "");
                return result;
            }
        }
    }

我得到了

0.12
1.2

作为输出

更新:

要查看是否正在降低Regex方法的正则表达式编译,我将正则表达式放在一个只构造一次的静态变量中。

            static Regex rex = new Regex("\\P{L}");
            public static string RemoveNonUnicodeLetters2(string input)
            {
                var result = rex.Replace(input,m => "");
                return result;
            }

但这对运行时没有影响。