Python: Как проверить, содержит ли строка в юникоде символ в регистре? - PullRequest
8 голосов
/ 18 августа 2010

Я делаю фильтр, в котором проверяю, не содержит ли строка в Юникоде (кодировка 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 ()?

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

Спасибо!

Ответы [ 3 ]

8 голосов
/ 18 августа 2010
import unicodedata as ud

def contains_cased(u):
  return any(ud.category(c)[0] == 'L' for c in u)
6 голосов
/ 18 августа 2010

Здесь - полный набор символов категории Unicode.

Буквенные категории включают в себя:

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 Ll и 937 x Lu, в общей сложности 2153 ... область для дальнейшего изучения того, что на самом деле означают Ll и Lu.

1 голос
/ 18 августа 2010

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

unicodedata.category(character)

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

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

...