Игнорировать регистр в строках Python

Как проще всего сравнивать строки в Python без учета регистра?

Конечно, можно сделать (str1.lower () <= str2.lower ()) и т. д., Но это создало две дополнительные временные строки (с очевидными накладными расходами alloc / g-c).

Думаю, я ищу эквивалент stricmp () в C.

[Требуется еще немного контекста, поэтому я продемонстрирую тривиальный пример:]

Предположим, вы хотите отсортировать длинный список строк. Вы просто выполняете theList.sort (). Это сравнение строк O (n * log (n)) без управления памятью (поскольку все строки и элементы списка - это своего рода умные указатели). Вы счастливы.

Теперь вы хотите сделать то же самое, но не обращайте внимания на регистр (давайте упростим и скажем все строки в формате ascii, поэтому проблемы с локалью можно игнорировать). Вы можете выполнить theList.sort (key = lambda s: s.lower ()), но тогда вы вызовете два новых распределения на сравнение, плюс нагрузка на сборщик мусора дублированными (опущенные) струны. Каждый такой шум управления памятью на порядки медленнее, чем простое сравнение строк.

Теперь, используя функцию, аналогичную stricmp (), вы выполняете: theList.sort (cmp = stricmp) и он такой же быстрый и удобный для памяти, как theList.sort (). Вы снова счастливы.

Проблема в том, что любое сравнение на основе Python без учета регистра включает неявную строку дублирования, поэтому я ожидал найти сравнения на основе C (возможно, в строке модуля).

Ничего подобного найти не удалось, отсюда и вопрос. (Надеюсь, это проясняет вопрос).

Эквивалент PHP: strcasecmp - nl3.php.net/strcasecmp

fijter 15.09.2008 17:04

ваши предположения ошибочны. list.sort () с ключом = означает ли нет «два новых выделения на одно сравнение». (list.sort с cmp =, с другой стороны, делает вызывает аргумент для каждого сравнения)

user3850 23.09.2008 17:45

попытался переименовать вопрос из Ignore case in python strings в What's closest to stricmp in Python for 7-bit ascii string comparison?, чтобы более точно отразить фактический вопрос оператора. основная проблема: unicode - это тоже «строка», но этот вопрос может ошибиться с полностью; см. комментарии tchrist

n611x007 15.04.2014 16:14

связанные: Как мне свернуть строку в Python 2?

jfs 29.09.2015 11:35
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
51
4
105 111
16
Перейти к ответу Данный вопрос помечен как решенный

Ответы 16

Я почти уверен, что вам нужно либо использовать .lower (), либо использовать регулярное выражение. Мне неизвестна встроенная функция сравнения строк без учета регистра.

Вот как вы это сделаете с re:

import re
p = re.compile('^hello$', re.I)
p.match('Hello')
p.match('hello')
p.match('HELLO')

Регулярные выражения без учета регистра могут использоваться только для проверки равенства (True / False), но не для сравнения (меньше / равно / больше)

tzot 16.09.2008 02:26

Вы можете создать подкласс str и создать свой собственный строковый класс без учета регистра, но ИМХО, это было бы крайне неразумно и создаст гораздо больше проблем, чем оно того стоит.

Для случайных или даже повторяющихся сравнений несколько дополнительных строковых объектов не должны иметь значения, если это не произойдет во внутреннем цикле вашего основного кода или у вас недостаточно данных, чтобы действительно заметить влияние на производительность. Посмотрите, если вы это сделаете: делать что-то «глупым» способом будет гораздо менее глупо, если вы также будете делать это меньше.

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

Нет встроенного эквивалента той функции, которую вы хотите.

Вы можете написать свою собственную функцию, которая преобразует в .lower () каждый символ за раз, чтобы избежать дублирования обеих строк, но я уверен, что это будет очень интенсивно и крайне неэффективно.

Если вы не работаете с очень длинными строками (настолько длинными, что при дублировании могут возникнуть проблемы с памятью), я бы оставил это простым и использовал

str1.lower() == str2.lower()

Ты будешь в порядке

«Никогда не говори никогда» :) «Нет встроенного эквивалента» является абсолютным; «Я не знаю встроенного аналога» было бы ближе к истине. locale.strcoll с учетом регистра LC_COLLATE (как en_US) является встроенным.

tzot 16.09.2008 02:29

Это неверный ответ. Единственный правильный способ - str1.fold() == str2.fold(), но для этого требуется расширение класса строки Python по умолчанию, который поддерживает полный регистр Unicode строки. Это недостающая функция.

tchrist 12.08.2011 01:56

@tchrist unclearr: есть ли такое расширение?

n611x007 15.04.2014 16:05

Используете ли вы это сравнение в очень часто выполняемом пути высокопроизводительного приложения? Или вы запускаете это на строках размером в мегабайты? Если нет, то вам не стоит беспокоиться о производительности и просто использовать метод .lower ().

Следующий код демонстрирует, что выполнение сравнения без учета регистра путем вызова .lower () для двух строк, каждая из которых имеет размер почти мегабайт, занимает около 0,009 секунды на моем настольном компьютере с частотой 1,8 ГГц:

from timeit import Timer

s1 = "1234567890" * 100000 + "a"
s2 = "1234567890" * 100000 + "B"

code = "s1.lower() < s2.lower()"
time = Timer(code, "from __main__ import s1, s2").timeit(1000)
print time / 1000   # 0.00920499992371 on my machine

Если это действительно чрезвычайно важный и критичный для производительности раздел кода, то я рекомендую написать функцию на C и вызывать ее из кода Python, поскольку это позволит вам выполнять действительно эффективный поиск без учета регистра. Подробности о написании модулей расширения C можно найти здесь: https://docs.python.org/exnding/exnding.html

вот как вы передаете материал в класс Timer. спасибо за решение совсем другого моего зуда :)

Manav 24.03.2011 16:32

Это совершенно неверно. Невозможно обнаружить, что ΣΤΙΓΜΑΣ и στιγμας одинаковы без учета регистра. Вы не должны использовать casemapping для сравнения регистра в Unicode. Вы должны использовать casefolding. Это разные вещи. Σ, σ, ς все такие же, как и S, ſ, с (что это вообще с s? :) и Μ, μ, µ. Есть бесчисленное множество других подобных обстоятельств, например, как weiß, WEIẞ, weiss, WEISS все одинаковы, или действенно, действенно. Вы необходимо использовать casefolds,, потому что casemap не работают.

tchrist 11.08.2011 20:47

Я не могу найти другого встроенного способа сравнения без учета регистра: рецепт поваренной книги питона использует lower ().

Однако вы должны быть осторожны при использовании более низкого значения для сравнения из-за Турецкая проблема I. К сожалению, Python не очень хорошо справляется с турецкими языками. ı преобразуется в I, но не преобразуется в ı. İ преобразуется в i, но i не преобразуется в İ.

Как вы видели, Python не очень надежно обрабатывает Unicode. В картах дела на это не обращают внимания. Очень грустный.

tchrist 11.08.2011 20:50

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

Обратите внимание, что этот метод можно использовать не только для обработки проблем с верхним / нижним регистром, но и для других типов сортировки, таких как сортировка по локали или сортировка заголовков «в стиле библиотеки», которая игнорирует ведущие статьи и иным образом нормализует данные перед их сортировкой.

вопрос является более общим, чем сам пример (на самом деле, в реальных сценариях жизни вы не хотите, чтобы вас беспокоили, прикрепляя строчную версию к каждой строке, которая может понадобиться icmp () позже), но даже в этом тривиальном примере вы не используете не хочу удваивать память только для того, чтобы иметь возможность сортировать ...

Paul Oyster 16.09.2008 00:15
Ответ принят как подходящий

В ответ на ваше разъяснение ...

Вы можете использовать ctypes для выполнения функции c "strcasecmp". Ctypes включен в Python 2.5. Он предоставляет возможность обращаться к dll и разделяемым библиотекам, таким как libc. Вот краткий пример (Python в Linux; см. Ссылку для справки по Win32):

from ctypes import *
libc = CDLL("libc.so.6")  // see link above for Win32 help
libc.strcasecmp("THIS", "this") // returns 0
libc.strcasecmp("THIS", "THAT") // returns 8

может также захотеть сослаться на документация strcasecmp

Не совсем уверен, что это быстрее или медленнее (не тестировал), но это способ использовать функцию C для сравнения строк без учета регистра.

~~~~~~~~~~~~~~

Код ActiveState - рецепт 194371: строки без учета регистра - это рецепт создания строкового класса без учета регистра. Это может быть немного излишне kill для чего-то быстрого, но может предоставить вам общий способ обработки нечувствительных к регистру строк, если вы планируете часто их использовать.

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

Paul Oyster 16.09.2008 00:37

Решение ctype - это то, что я искал, спасибо. Для справки, вот код win32: from ctypes import * clib = cdll.LoadLibrary ("msvcrt") theList = ["abc", "ABC", "def", "DEF"] * 1000000 theList.sort (cmp = clib._stricmp)

Paul Oyster 16.09.2008 12:27

это намного медленнее. смотри мой ответ!

user3850 23.09.2008 18:11

Я считаю, что это дает неправильный ответ для строк с нулями.

Darius Bacon 29.10.2008 19:28

Нет, это неправильно. Единственное правильное решение - сравнить их регистры Unicode. Иначе облажаетесь.

tchrist 11.08.2011 20:37

@tchrist в качестве примечания, строка 'unicode' не является предметом вопроса. Тем не менее, ваш комментарий, который, кажется, указывает любому, кто приходит сюда с надеждой на Unicode в правильном направлении, неоценим. Я пытаюсь отредактировать заголовок вопроса, чтобы более точно отразить его.

n611x007 15.04.2014 16:09

Для сортировки списков значений с использованием дорогостоящих в вычислении ключей рекомендуется использовать так называемый «декорированный шаблон». Он состоит просто в построении списка кортежей (ключей, значений) из исходного списка и сортировке этого списка. Затем просто удалить ключи и получить список отсортированных значений:

>>> original_list = ['a', 'b', 'A', 'B']
>>> decorated = [(s.lower(), s) for s in original_list]
>>> decorated.sort()
>>> sorted_list = [s[1] for s in decorated]
>>> sorted_list
['A', 'a', 'B', 'b']

Или, если вам нравятся однострочные:

>>> sorted_list = [s[1] for s in sorted((s.lower(), s) for s in original_list)]
>>> sorted_list
['A', 'a', 'B', 'b']

Если вы действительно беспокоитесь о стоимости вызова lower (), вы можете просто хранить кортежи (пониженная строка, исходная строка) везде. Кортежи - это самый дешевый вид контейнеров в Python, они также являются хешируемыми, поэтому их можно использовать в качестве ключей словаря, членов набора и т. д.

кортежи дешевы, но дублирование строк - нет ...

Paul Oyster 16.09.2008 12:25

это также то, что делает сортировка python с аргументом key =.

user3850 23.09.2008 18:28

Это 7-битный образ мышления, который совершенно не подходит для данных Unicode. Вы должны использовать либо полный регистр Unicode, либо основную силу сортировки в соответствии с алгоритмом сортировки Unicode. Да, в любом случае это означает новые копии строки, но, по крайней мере, тогда вы можете провести двоичное сравнение вместо того, чтобы рыться в таблицах для каждой кодовой точки.

tchrist 11.08.2011 20:50

Ваш вопрос подразумевает, что вам не нужен Unicode. Попробуйте следующий фрагмент кода; если это сработает для вас, все готово:

Python 2.5.2 (r252:60911, Aug 22 2008, 02:34:17)
[GCC 4.3.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import locale
>>> locale.setlocale(locale.LC_COLLATE, "en_US")
'en_US'
>>> sorted("ABCabc", key=locale.strxfrm)
['a', 'A', 'b', 'B', 'c', 'C']
>>> sorted("ABCabc", cmp=locale.strcoll)
['a', 'A', 'b', 'B', 'c', 'C']

Уточнение: в случае, если это не очевидно на первый взгляд, locale.strcoll кажется вам нужной функцией, избегая "повторяющихся" строк str.lower или locale.strxfrm.

Глобальная настройка locale.setlocale () явно излишняя (слишком глобальная).

Paul Oyster 16.09.2008 12:24

Я не знаю, что такое «очевидное излишество», а «глобальный» параметр может быть настолько локализован, насколько вам нравится (кроме случаев, когда вы работаете с потоками и вам нужно, чтобы некоторые потоки были локализованы, а некоторые нет по какой-то причине).

tzot 30.10.2008 02:52

Это единственное решение, которое дает результаты, которые могут правильно взаимодействовать с нечувствительными к регистру утилитами, такими как сортировка Unix с параметром -f. Например, str.lower заставляет A_ сортировать перед AA.

Neil Mayhew 09.01.2011 04:38

Вы не можете использовать локали POSIX и strcoll, потому что они ненадежны для разных платформ. Вы должны использовать регистр Unicode, который гарантированно будет работать одинаково везде.

tchrist 11.08.2011 20:39

Вот тест, показывающий, что использование str.lower быстрее, чем предложенный метод принятого ответа (libc.strcasecmp):

#!/usr/bin/env python2.7
import random
import timeit

from ctypes import *
libc = CDLL('libc.dylib') # change to 'libc.so.6' on linux

with open('/usr/share/dict/words', 'r') as wordlist:
    words = wordlist.read().splitlines()
random.shuffle(words)
print '%i words in list' % len(words)

setup = 'from __main__ import words, libc; gc.enable()'
stmts = [
    ('simple sort', 'sorted(words)'),
    ('sort with key=str.lower', 'sorted(words, key=str.lower)'),
    ('sort with cmp=libc.strcasecmp', 'sorted(words, cmp=libc.strcasecmp)'),
]

for (comment, stmt) in stmts:
    t = timeit.Timer(stmt=stmt, setup=setup)
    print '%s: %.2f msec/pass' % (comment, (1000*t.timeit(10)/10))

типичное время на моей машине:

235886 words in list
simple sort: 483.59 msec/pass
sort with key=str.lower: 1064.70 msec/pass
sort with cmp=libc.strcasecmp: 5487.86 msec/pass

Итак, версия с str.lower не только самая быстрая, но и самая портативная и питоничная из всех предлагаемых здесь решений. Я не анализировал использование памяти, но в оригинальном плакате все еще не было веских причин для беспокойства. Кроме того, кто сказал, что вызов модуля libc не дублирует никаких строк?

NB: строковый метод lower() также имеет то преимущество, что он зависит от локали. Что-то, что вы, вероятно, не поймете при написании собственного «оптимизированного» решения. Тем не менее, из-за ошибок и отсутствующих функций в Python такое сравнение может дать неверные результаты в контексте Юникода.

Конечно, память - это проблема, поскольку более 99,9% времени .lower () приходится на выделение памяти. Кроме того, на машинах (Windows), которые я проверял, подход key = _stricmp был в 4-5 раз быстрее и без памяти.

Paul Oyster 07.10.2008 16:17

В 4-5 раз быстрее, чем .lower-method, означает, что он в 2 раза быстрее, чем простой случай сортировки. как это может быть?!?

user3850 10.10.2008 23:21

@hop все слова в списке слов, который вы проверяете, уже в нижнем регистре. Это может дать вам результаты, далекие от результатов Павла.

Virgil Dupras 16.01.2010 22:08

@hop снова: забудь. Я попытался отсортировать тот же список с помощью str.upper, и результаты примерно такие же.

Virgil Dupras 16.01.2010 22:13

@virgil: также, в моем регионе более двух третей всех слов начинаются с заглавной буквы;)

user3850 16.01.2010 22:21

@hop представленный вами анализ действительно хорош. это показывает (особенно мне), что иногда лучше не считать циклы и байты в уме.

Xolve 13.11.2010 16:08

Вопрос для уточнения: что вы подразумеваете под str.lower, зависит от локали? Я спрашиваю, потому что в вашем ответе нет другого упоминания о вещах, связанных с локалью, например, позвонив в locale.setlocale.

tzot 23.03.2011 01:05

@ ΤΖΩΤΖΙΟΥ: из документации: «Для 8-битных строк этот метод зависит от локали». Мне не нужно явно устанавливать locale, так как это обрабатывается моей системной конфигурацией.

user3850 23.03.2011 02:22

@hop: мой собственный тест показывает, что метод libc в 3 раза быстрее, чем .lower (). На самом деле вы демонстрируете, что сортировка с помощью ключа более эффективна, чем сортировка с помощью cmp.

bukzor 18.05.2011 01:54

@hop: тогда ваше утверждение "str.lower - самый быстрый на сегодняшний день" вводит в заблуждение.

bukzor 18.05.2011 21:12

Это тоже неправильно, потому что, если вы не используете регистр Unicode, вы получите самые разные ответы.

tchrist 11.08.2011 20:38

@tchrist: ну да, но 1) это относится ко всем решениям и 2) с помощью strcasecmp вы даже не можете решить эту проблему.

user3850 12.08.2011 01:42

@hop: проверьте bugs.python.org на наличие ошибок Unicode. Я только что представил кучу тестовых примеров, показывающих, где Python дает сбой, не используя casefolding. Если мне нужно выбирать между быстрым и правильным, я знаю, какой из них выберу каждый раз.

tchrist 12.08.2011 01:54

@tchrist: я не совсем понимаю, к чему вы идете. какое конкретное предлагаемое решение?

user3850 12.08.2011 13:55

@hop: должен быть строковый метод, обеспечивающий регистр Unicode, тогда вы просто выполняете простое сравнение. Не связывайтесь с уродливыми антипортативными локали, черт возьми, они так же плохи, как страницы кода GAG в µsløth. string.lower(), string.title(), string.upper() у вас уже есть, но вам нужен string.fold(), чтобы вы могли использовать str1.fold() == str2.fold(). Его нет в Python API. Обратите внимание, как это работает в отделении интенсивной терапии. Потому что это то, что вам нужно; это как, вы выполняете нечувствительные к регистру сравнения текста Unicode, не углубляясь в алгоритм сортировки Unicode.

tchrist 12.08.2011 14:31

@tchrist: есть ли еще решение настоящий, которое вы можете предложить? некоторые из нас должны отправить код сейчас же. Я очень ценю ваши знания и участие в этой теме, но использование key= с вашим fold() все равно лучше, чем использование cmp= с вашим fold(), а PyICU все равно будет лучше, чем взломать что-то вместе с ctypes, и что? является? ваш? точка?

user3850 12.08.2011 17:30

@tchrist: Ладно, раз уж тебе нужно было перейти на личную тему, это последнее, что я скажу по этому поводу. Вопрос касался проблем с распределением памяти, этот ответ - о том, чтобы показать, что оптимизация для дублирования строк не улучшит, а снизит производительность, и у ВАС даже нет ни малейшего доказательства того, что во всем этом участвует человеческий язык. OP может сравнивать строки base64 для всего, что вы знаете. Так что перестань быть таким ханжеским, пожалуйста.

user3850 12.08.2011 21:26

Вероятно, лучше не называть чей-то ответ «глупым».

Chris Dutrow 09.11.2011 21:46

@DutrowLLC: да, наверное, ты не прав.

user3850 10.11.2011 18:07

Этот тест, похоже, полностью игнорирует время, которое версия .lower() тратит на сборщик мусора .. верно?

Izkata 21.12.2012 23:20

@ Изката: да. Timer.timeit отключает сборку мусора во время теста.

jfs 11.01.2015 16:41

Включение gc еще больше ухудшает относительную производительность метода libc. Я обновил свой ответ, чтобы запустить timeit () с включенным gc.

user3850 15.01.2015 16:53

Просто используйте метод str().lower(), если не важна высокая производительность - в этом случае напишите этот метод сортировки как расширение C.

«Как написать расширение Python» кажется неплохим вступлением ..

Что еще более интересно, Это руководство сравнивает использование библиотеки ctypes с написанием внешнего модуля C (ctype значительно медленнее, чем расширение C).

Когда что-то плохо поддерживается в стандартной библиотеке, я всегда ищу пакет PyPI. С виртуализацией и повсеместным распространением современных дистрибутивов Linux я больше не избегаю расширений Python. PyICU, похоже, отвечает всем требованиям: https://stackoverflow.com/a/1098160/3461

Теперь есть вариант - чистый питон. Хорошо протестировано: https://github.com/jtauber/pyuca


Старый ответ:

Мне нравится решение с регулярными выражениями. Вот функцию, которую вы можете скопировать и вставить в любую функцию благодаря поддержке блочной структуры Python.

def equals_ignore_case(str1, str2):
    import re
    return re.match(re.escape(str1) + r'\Z', str2, re.I) is not None

Так как я использовал совпадение вместо поиска, мне не нужно было добавлять курсор (^) к регулярному выражению.

Примечание: Проверяет только равенство, что иногда бывает необходимо. Я бы также не стал говорить, что мне это нравится.

[Я бы хотел, чтобы для этого был виртуальный штамп] Не используйте $, используйте \Z. Прочтите фантастическое руководство, чтобы узнать, что на самом деле делает $; не полагайтесь на легенды, догадки или что-то еще.

John Machin 26.04.2010 07:54

Я изменил это. Я также включил функцию вики сообщества для своего ответа. Спасибо.

Benjamin Atkin 26.04.2010 08:38

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

martineau 29.08.2014 18:09

@martineau, спасибо. Я добавил примечание, а также немного поискал и нашел решение, которое, как мне кажется, мне было бы более комфортно, и обновил свой ответ с его помощью. Однако это не полный ответ. Надеюсь, кто-нибудь (я, если я дойду до этого) узнает, как работает одна из этих библиотек, и предоставит образец кода.

Benjamin Atkin 03.09.2014 23:10

Да, похоже, что расширение pyuca (Python Unicode Collation Algorithm) может работать, потому что в отчете, на котором оно основано - Алгоритм сортировки Unicode (UCA) - говорится: «Различия в регистре (верхний и нижний регистры) обычно игнорируются».

martineau 04.09.2014 00:16

В этом вопросе задаются две разные вещи:

  1. Как проще всего сравнивать строки в Python без учета регистра?
  2. Думаю, я ищу эквивалент stricmp () в C.

Поскольку на № 1 уже дан очень хороший ответ (например: str1.lower () <str2.lower ()), я отвечу на № 2.

def strincmp(str1, str2, numchars=None):
    result = 0
    len1 = len(str1)
    len2 = len(str2)
    if numchars is not None:
        minlen = min(len1,len2,numchars)
    else:
        minlen = min(len1,len2)
    #end if
    orda = ord('a')
    ordz = ord('z')

    i = 0
    while i < minlen and 0 == result:
        ord1 = ord(str1[i])
        ord2 = ord(str2[i])
        if ord1 >= orda and ord1 <= ordz:
            ord1 = ord1-32
        #end if
        if ord2 >= orda and ord2 <= ordz:
            ord2 = ord2-32
        #end if
        result = cmp(ord1, ord2)
        i += 1
    #end while

    if 0 == result and minlen != numchars:
        if len1 < len2:
            result = -1
        elif len2 < len1:
            result = 1
        #end if
    #end if

    return result
#end def

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

Я работаю только со строками ascii, я не уверен, как это будет вести себя с юникодом.

import re
if re.match('tEXT', 'text', re.IGNORECASE):
    # is True

Другие вопросы по теме