Python: как проверить, содержит ли строка Unicode символ в регистре?

Я делаю фильтр, в котором проверяю, содержит ли строка Unicode (кодировка utf-8) символы верхнего регистра (на всех языках). Меня устраивает, если строка вообще не содержит никаких символов в регистре.

Например: «Привет!» не пройдет фильтр, но "!" должен пройти фильтр, поскольку "!" не регистровый персонаж.

Я планировал использовать метод islower (), но в приведенном выше примере «!». Islower () вернет False.

Согласно документации Python, «метод unicode python islower () возвращает True, если все символы в регистре строки Unicode являются строчными, а строка содержит хотя бы один символ в регистре, в противном случае он возвращает False».

Поскольку метод также возвращает False, когда строка не содержит символов в регистре, т.е. "!", Я хочу проверить, содержит ли строка какой-либо символ в регистре.

Что-то вроде этого....

string = unicode("!@#$%^", 'utf-8')

#check first if it contains cased characters
if not contains_cased(string):
     return True

return string.islower():

Есть предложения по функции contains_cased ()?

Или, возможно, другой подход к реализации?

Спасибо!


person Albert    schedule 18.08.2010    source источник
comment
Ответ, который вы приняли, кажется неверным. Смотрите мой ответ.   -  person John Machin    schedule 19.08.2010


Ответы (3)


Здесь представлена ​​полная информация о категориях символов Юникода.

Категории букв включают:

Ll -- lowercase
Lu -- uppercase
Lt -- titlecase
Lm -- modifier
Lo -- other

Обратите внимание, что Ll <-> islower(); аналогично для Lu; (Lu or Lt) <-> istitle()

Вы можете прочитать сложное обсуждение корпуса, которое включает в себя обсуждение Lm букв.

Слепое рассмотрение всех "букв" как заключенных в регистр явно неверно. Категория Lo включает 45301 кодовую точку в BMP (подсчитано с использованием Python 2.6). Большая часть из них будет состоять из слогов хангыля, иероглифов CJK и других восточноазиатских символов - очень трудно понять, как их можно считать «заключенными в регистр».

Вы можете рассмотреть альтернативное определение, основанное на (неуказанном) поведении "заключенных в регистр символов", которое вы ожидаете. Вот простая первая попытка:

>>> cased = lambda c: c.upper() != c or c.lower() != c
>>> sum(cased(unichr(i)) for i in xrange(65536))
1970
>>>

Интересно, что существует 1216 x L1 и 937 x Lu, всего 2153 ... возможность для дальнейшего исследования того, что на самом деле означают Ll и Lu.

person John Machin    schedule 18.08.2010
comment
@ Джон: Вау. Спасибо за ваше объяснение. Мне потребовалось время, чтобы понять это. Я просмотрел вашу ссылку и думаю, что мне нужно изучить ее более подробно. У меня такое чувство, что то, что я собираюсь выяснить, заставит меня пересмотреть большую часть моего кода. Ой. Спасибо! - person Albert; 19.08.2010
comment
@Albert: Не паникуй. Как я уже намекал, сначала дайте определение тому, что вы имеете в виду под корпусом. Какое другое лечение вы будете применять к символам с регистром по сравнению с символами без регистра? В моем примере определение было char, которое имеет "партнер" в верхнем или нижнем регистре. Некоторая (возможно, вся) разница между символами 1970 и 2153, по-видимому, связана с символами, которые классифицируются как Ll, потому что они выглядят как символы нижнего регистра, но не имеют партнера Lu, и наоборот - вам нужно решить, подходят ли они для ваших целей. Кстати, вы можете изменить свой принятый ответ :-) - person John Machin; 19.08.2010
comment
@John: Ну, я на самом деле делаю API для своего веб-сервиса. Мой веб-сервис принимает ключ, который соответствует определенной записи в моей базе данных. Ключ чувствителен к регистру, и ключ может состоять из любого символа Юникода. Поэтому, чтобы нормализовать весь ввод, я переведу все ключевые запросы в нижний регистр (если у них есть эквиваленты в верхнем регистре). Следствием этого является то, что когда я создаю ключи записи (которые могут настраивать мои пользователи), я не могу принять какой-либо символ верхнего регистра, который может быть преобразован в эквивалент нижнего регистра функцией toLower (). Поэтому я пытаюсь создать для этого фильтр. Какие-либо предложения? - person Albert; 20.08.2010
comment
@Albert: Если ваши ключи чувствительны к регистру, зачем вы их нормализуете ??? что означает запись ключей, которые пользователи могут настраивать ??? любой символ юникода vs не может принимать символы верхнего регистра ??? Чтобы ответить на ваш вопрос буквально: похоже, вы не можете принять символ c, когда c.lower() != c, что означает, что вы не можете принять никакой ключ, если key.lower() != key. Я думаю, вам следует начать НОВЫЙ ВОПРОС, объясняя, что именно вы пытаетесь сделать, с примеров. BTW1: не забудьте сначала принять ответ на этот вопрос. BTW2: Python не имеет функции toLower ... - person John Machin; 21.08.2010
comment
@ Джон: Моя ошибка. Я имел в виду функцию lower (). Хорошо, я начну новый вопрос. Спасибо! - person Albert; 21.08.2010
comment
@ Джон: Я уважаю ваш опыт работы с юникодом. У меня новый вопрос, как вы думаете, можете ли вы взглянуть на него, а также на ответы, если они верны. Спасибо! stackoverflow.com/questions/3536397/ - person Albert; 21.08.2010
comment
Вы ошибочно приняли строчные буквы за строчные кодовые точки. Это строчные кодовые точки, но не строчные: U + 0345 GC=Mn COMBINING GREEK YPOGEGRAMMENI, U + 2176 GC=Nl SMALL ROMAN NUMERAL SEVEN, U + 24DA GC=So CIRCLED LATIN SMALL LETTER K. И это строчные буквы, которые не меняют регистр в верхнем регистре: U + 00AA GC=Ll FEMININE ORDINAL INDICATOR, U + 0262 GC=Ll LATIN LETTER SMALL CAPITAL G, U + 02B0 GC=Lm MODIFIER LETTER SMALL H, U + 2093 GC=Lm LATIN SUBSCRIPT SMALL LETTER X, U + 210A GC=Ll SCRIPT SMALL G и U + 1D521 GC=Ll MATHEMATICAL FRAKTUR SMALL D. - person tchrist; 27.08.2011

использовать модуль unicodedata,

unicodedata.category(character)

возвращает "Ll" для строчных букв и "Lu" для прописных.

здесь вы можете найти список категорий символов Юникода.

person mykhal    schedule 18.08.2010

person    schedule
comment
Арг Алекс, ты чего-то не знаешь? - person e-satis; 18.08.2010
comment
+1: рабочее решение (по сравнению с красивым объяснением без исполняемого кода Джона Мачина) - person oDDsKooL; 03.07.2012