检查c#字符串中的每个字符是否都是相同的字符

时间:2013-05-23 10:03:16

标签: c#

从任何字符串开始,我需要确定该字符串是否只包含一个或多个指定单个字符的实例。例如“£”会通过我的测试,“wertf”会失败。我采取的方法如下:

string source = "any string";
char[] candidate = source.ToCharArray();
char validCharacter = '£';

    if (candidate.Length > 0)
    {
        // (code removed) if candidate length = 1 then just test candidate[0] against validCharacter
        bool isValid = true;
        int index = 0;

        while (index < candidate.Length - 1)
        {
            if (candidate [index] != validCharacter )
            {
                isValid = false;
                break;
            }

            index++;
        }

        if (isValid)
        {
            // success, do what needs doing
        }
    }

正如您所料,这是有效的,但我不禁觉得我可能会错过这里的一招。是否有一种更好,更简洁的方法,这样做不会牺牲上述的清晰度?

9 个答案:

答案 0 :(得分:9)

您只需使用更简单的代码检查字符串是否具有相同的字符:

if (source.Distinct().Count() == 1)
{
    // Pass
}

修改:

如果您需要检查字符串是否只包含一个或多个指定单个字符的实例,则可以使用All

if (input.All(c => c == specificChar))
{
    // Pass
}

答案 1 :(得分:3)

使用Enumerable.All<TSource> Method

bool result = (str.Length > 0 && str.All(r=> r == str[0]));

这比使用DistinctCount()

更有效

对于您的情况,它可以是:

string source = "any string";
char validCharacter = '£';
bool result = source.Length > 0 && source.All(r=> r == validCharacter);

答案 2 :(得分:2)

使用Distinct()删除重复项并比较字符数。

var pass = mystring.Count() > mystring.Distinct().Count();

修改

我误读并认为它是测试字符串中任何字符的副本。以下内容适用于“仅一个字符的一个或多个实例”。

mystring.Distinct().Count() == 1

答案 3 :(得分:2)

以下是一种方法:

if(source[0] != validCharacter) return false;

bool isValid = true;
for(int i = 1 ; i < source.Length; i++)
{
  if(validCharacter != source[i])
  {
    isValid = false;
    break;
  }
}

注意事项:如果第一个字符不匹配,立即失败。 string已经实现了IEnumerable<char>,因此无需将ToCharArray与额外分配一起使用。循环从索引1开始,始终与第一个项目进行比较,并在失败后立即中断。

对于长字符串,这可能比Distinct更有效。

答案 4 :(得分:1)

string test1 = "Test";
string test2 = "TTTT";

test1.All(a => a == test1[0]);
test2.All(a => a == test2[0]);

答案 5 :(得分:1)

在您的算法中,您不需要.ToCharArray()。只需使用source[index]检索字符即可。这样你只会阅读内存并只阅读每个角色一次。

您的代码是最佳解决方案。使用LINQ有许多技巧,但大多数会表现得更糟。使用source.Trim(source[0])等代码的任何技巧都会导致不必要的新字符串创建,从而导致性能下降。

请参阅Oded的答案♦缩短现有代码。

答案 6 :(得分:1)

您的代码可能是最快的,您可以使用for代替while

来压缩它
for (int i = 0; i < source.Length; i++) {
    // existing equality check
}

或者,这是另一个低效但更紧凑的方法(因为它在内存中创建一个新字符串并进行检查):

if (source == new String('£', source.Length)) {
    // valid
}

答案 7 :(得分:0)

你可以试试这个:

 string str = "test";
            char b = '£';
            bool isValid = false;
            foreach (char a in str) 
            {
                if (!a.Equals(b)) 
                {
                    isValid = false;
                }
            }

答案 8 :(得分:0)

if(Regex.IsMatch(candidate, "^£+$")) {
   // whatever it is you want to do
}

...当然......

if(Regex.IsMatch(candidate, "^" + Regex.Escape(validChar) + "+$") { ... }

Regex.Escape()如果validChar是正则表达式中有意义的字符,例如*.等。

这些是简短的,声明性的(只要读者理解正则表达式),高效,性能可扩展到长字符串,而成语扩展到更复杂的模式。