C# Char.IsLetter() 无法正常工作

C# Char.IsLetter() not working properly

各位。 我为我糟糕的英语感到抱歉。 我有一个很简单的任务: 一个字符一个字符地读取文件,并计算每个字母。语言无所谓。 起初,我使用了一个包含所有受限字符的字符串:

"1234567890`~!@#$%^&*()_+-=!№;%:?*(){}[];:|',./<>?  "    

这是一个愚蠢的想法,所以我决定使用:

!Char.IsLetter(data[i].letter)
data.RemoveAt(i);

没有成功。甚至以下都不起作用(好吧,我没想到它会起作用)

                if(Char.IsDigit(data[i].letter) || Char.IsSymbol(data[i].letter)||Char.IsControl(data[i].letter) ||Char.IsNumber(data[i].letter) ||Char.IsPunctuation(data[i].letter) ||Char.IsSeparator(data[i].letter) ||Char.IsSymbol(data[i].letter) ||Char.IsWhiteSpace(data[i].letter))
                data.RemoveAt(i);

它仍然会让一些数字和符号溜走。 最烦人的是'\r',我无法摆脱它。 我需要一个可以判断字符是否为字母的解决方案。 我是新手,越简单越好。 提前致谢!

改用正则表达式

Regex.IsMatch(input, @"^[a-zA-Z]+$");

或更简单

Regex.IsMatch(input, "[a-zA-Z]");

要简单地计算对象数组中的字母数:

data.Count(x => char.IsLetter(x.letter));

这使用 LINQ Count 方法并为 letter 字段调用 char.IsLetter 以确定是否应将每个字符添加到计数中。

示例:(只有字符串而不是对象数组)

var data = "ABC_123_\r_%$#";
var count = data.Count(char.IsLetter);
Console.WriteLine(count);

将按预期打印 3

请注意,您必须将:using System.Linq; 添加到您的文件的顶部,如果它还不存在的话。

您的问题是您在迭代期间修改了集合

using System.Collections.Generic;
using System.Linq;

namespace Example
{
  class Program
  {
    static void Main(string[] args)
    {
        List<char> data =  "1234567890".ToList();
        //This does not remove all the element!!!
        for (int i = 0; i < data.Count; i++)
            data.RemoveAt(i);
    }
  }
}

你需要这个

static void Main(string[] args)
{
        List<char> data = "1234567890".ToList();

        List<char> toDelete = new List<char>();

         for (int i = 0; i < data.Count; i++)
            toDelete.Add(data[i]);

        for (int i = 0; i < toDelete.Count; i++)
            data.Remove(toDelete[i]);
}

或使用更少的行(如您所见,IsLetter 工作正常,\r\n 没有问题)

 List<char> data = (Environment.NewLine + "1234567890").ToList();
 data = data.Where(l => char.IsLetter(l)).ToList();

如果您的 data 实际上是 List<Data>(),并且您的代码如下所示:

        for (int i = 0; i < data.Count; i++)
            if (!Char.IsLetter(data[i].letter))
                data.RemoveAt(i);

正在使用

public class Data
{
    public char letter { get; set; }
}

然后你有一个错误 - 你将跳过删除字母后的每个字母的测试,因为对 RemoveAtt(i) 的调用会将所有后续列表条目的索引减少 1。相反你应该使用 RemoveAll():

        data.RemoveAll(d => !char.IsLetter(d.letter));