Обнаружение, является ли строка всеми CAPS - PullRequest
48 голосов
/ 15 января 2009

В C # есть способ определить, является ли строка заглавными буквами?

Большинство строк будут короткими (т. Е. Не более 100 символов)

Ответы [ 11 ]

89 голосов
/ 15 января 2009

Нет необходимости создавать новую строку:

bool IsAllUpper(string input)
{
    for (int i = 0; i < input.Length; i++)
    {
        if (!Char.IsUpper(input[i]))
             return false;
    }

    return true;
}

Редактировать: Если вы хотите пропустить не алфавитные символы ( Оригинальная реализация OP не делает, но его / ее комментарии указывают, что они могут захотеть ):

   bool IsAllUpper(string input)
    {
        for (int i = 0; i < input.Length; i++)
        {
            if (Char.IsLetter(input[i]) && !Char.IsUpper(input[i]))
                return false;
        }
        return true;
    }
72 голосов
/ 15 января 2009

Мне нравится подход LINQ.

Если вы хотите ограничить его всеми заглавными буквами (т.е. без пробелов и т. Д.):

return input.All(c => char.IsUpper(c));

или с помощью преобразования группы методов:

return input.All(char.IsUpper);

Если вы хотите просто запретить строчные буквы:

return !input.Any(c => char.IsLower(c));

или

return !input.Any(char.IsLower);
56 голосов
/ 15 января 2009

Простой

if (input.ToUpper() == input)
{
    // string is all upper
}
14 голосов
/ 16 января 2009

Убедитесь, что ваше определение заглавных букв совпадает. Определение заглавных букв.

ToUpper () в .Net является лингвистической операцией. В некоторых языках правила использования заглавных букв не так просты. Турецкий Я известен этим .

// Meaning of ToUpper is linguistic and depends on what locale this executes
// This test could pass or fail in ways that surprise you.
if (input.ToUpper() == input) 
{
    // string is all upper
}

Вы можете использовать

// Meaning of ToUpper is basically 'ASCII' ToUpper no matter the locale.
if (input.ToUpper(CultureInfo.InvariantCulture) == input) 
{
    // string is all upper
}

У вас может возникнуть соблазн сэкономить память, выполняя ввод заглавных букв

MSDN предостерегает от этого

for(int i = 0; i < input.Length; i++) {
   if(input[i] != Char.ToUpper(input[i], CultureInfo.InvariantCulture)) {
     return false;
   }
}

Приведенный выше код вводит ошибку. Некоторые неанглийские «буквы» требуют двух символов .net для кодирования (суррогатная пара). Вы должны обнаружить эти пары и использовать их как одну единицу.

Кроме того, если вы опускаете информацию о культуре для получения лингвистической заглавной буквы, вы вносите ошибку, из-за которой в некоторых регионах ваш алгоритм заглавной буквы домашнего варки не согласуется с алгоритмом .net для этой локали.

Конечно, ничего из этого не имеет значения, если ваш код никогда не будет работать за пределами англоязычных локалей или никогда не получит неанглийский текст.

8 голосов
/ 15 января 2009

Использование

if (input == input.ToUpper())
7 голосов
/ 15 января 2009

Я бы преобразовал строку во все заглавные буквы (с ToUpper), а затем сравнил бы это с оригиналом (используя Equals). Должно быть выполнимо в одной строке кода.

return s.Equals(s.ToUpper())

4 голосов
/ 15 января 2009

Если для этого нужен хороший результат, я предполагаю, что это часто случается. Если это так, примите решение и сделайте это несколько миллионов раз и оцените его время. Я подозреваю, что то, что у вас есть, лучше, чем другие решения, потому что вы не создаете новый объект для сбора мусора, который нужно очистить, и вы не можете сделать копию строки, не выполняя итерации по ней.

1 голос
/ 31 октября 2018

Вы также можете вызвать функцию Windows, которая сообщит вам структуру вашей строки.

GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, s, s.Length, ref characterTypes);

Вы предоставляете ему массив UInt16 той же длины, что и ваша строка, и он заполняет каждый элемент битовой комбинацией флагов:

  • C1_UPPER (0x0001): прописные буквы
  • C1_LOWER (0x0002): строчные буквы
  • C1_DIGIT (0x0004): десятичные цифры
  • C1_SPACE (0x0008): пробелы
  • C1_PUNCT (0x0010): Знаки пунктуации
  • C1_CNTRL (0x0020): управляющие символы
  • C1_BLANK (0x0040): пустые символы
  • C1_XDIGIT (0x0080): шестнадцатеричные цифры
  • C1_ALPHA (0x0100): любой лингвистический символ: алфавитный, слоговый или идеографический. Некоторые символы могут быть буквенными, без прописных или строчных букв
  • C1_DEFINED (0x0200): определенный символ, но не один из других типов C1_ *

Итак, если вы изучили строку:

Здравствуйте, "42"!

Вы получите результаты

[0x210, 0x301, 0x382, 0x302, 0x302, 0x302, 0x210, 0x248, 0x210, 0x284, 0x284, 0x210, 0x210]

Который разбивается на:

|            | H | e | l | l | o | , |   | " | 4 | 2 | " | ! |
|------------|---|---|---|---|---|---|---|---|---|---|---|---|
| Defined    | X | X | X | X | X | X | X | X | X | X | X | X |
| Alpha      | x | x | x | x | x |   |   |   |   |   |   |   |
| XDigit     |   | x |   |   |   |   |   |   | x | x |   |   |
| Blank      |   |   |   |   |   |   | x |   |   |   |   |   |
| Cntrl      |   |   |   |   |   |   |   |   |   |   |   |   |
| Punct      |   |   |   |   |   | x |   |   |   |   | x | x |
| Space      |   |   |   |   |   |   | x |   |   |   |   |   |
| Digit      |   |   |   |   |   |   |   |   | x | x |   |   |
| Lower      |   | x | x | x | x |   |   |   |   |   |   |   |
| Upper      | x |   |   |   |   |   |   |   |   |   |   |   |
1 голос
/ 03 августа 2017

Другой подход

return input.Equals(input.ToUpper(), StringComparison.Ordinal)
0 голосов
/ 15 января 2009

Регулярные выражения приходят на ум. Обнаружил это там: http://en.csharp -online.net / Check_if_all_upper_case_string

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...