Проблема с регулярным выражением в Python - PullRequest
1 голос
/ 20 марта 2019

У меня есть функция в python, которая возвращает кортеж заданного ключа для алгоритма Natural-Sort / Human.

См. fake _human_key .

Но янужно это изменить, чтобы заменить немецкие умлауты их стандартными алфавитными символами.

Короче говоря, я хочу избавиться от Ä, Ö, Ü, ß для сортировки.

Кроме того, случай должен не .Маленький d должен иметь тот же приоритет, что и заглавный D ...

Для умлаутов я использую функцию замены, которая кажется довольно неловким способом сделать это ...: - /Понятия не имею ... Есть предложения?

Также я не могу переписать это, чтобы избавиться от чувствительности к регистру ...

Пока у меня есть:

def _human_key(key):
    key = key.replace("Ä", "A").replace("Ö", "O").replace("Ü", "U")\
          .replace("ä", "a").replace("ö", "o").replace("ü", "u")\
          .replace("ß", "s")
    parts = re.split(r'(\d*\.\d+|\d+)', key)   
    return tuple((e.swapcase() if i % 2 == 0 else float(e))
            for i, e in enumerate(parts))
    return parts

Примеры: у меня есть значения

 Zabel
 Schneider
 anabel
 Arachno
 Öztürk
 de 'Hahn

, которые я хочу отсортировать;в настоящее время это ставит:

anabel
de 'Hahn
Arachno
Öztürk
Schneider
Zabel

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

Ожидание:

anabel
Arachno
de 'Hahn   ( <-- because "d" comes after "a")
Öztürk
Schneider

Я считаю, что замена не является правильным способомчтобы решить проблему с умляутами, но не могу найти лучшего решения.

Обновление / Справочная информация:

Я звоню это извне, из класса "QSortFilterProxyModel", мне нужноэто для сортировки строк по их нажатым столбцам.У меня есть QTreeView, который отображает набор результатов из базы данных, и один столбец содержит немецкие фамилии, это фон.

class HumanProxyModel(QtCore.QSortFilterProxyModel):
    def lessThan(self, source_left, source_right):
        data_left = source_left.data()
        data_right = source_right.data()
        if type(data_left) == type(data_right) == str:            
            return _human_key(data_left) < _human_key(data_right)            
        return super(HumanProxyModel, self).lessThan(source_left, source_right)

Ответы [ 2 ]

1 голос
/ 20 марта 2019

это помогает?

import locale
locale.setlocale(locale.LC_ALL, "")

lst = ['Zabel', 'Schneider', 'anabel', 'Arachno', 'Öztürk', 'de Hahn']

print(sorted(lst, key=locale.strxfrm))

дал мне:

['anabel', 'Arachno', 'de Hahn', 'Öztürk', 'Schneider', 'Zabel']

Чтобы идти дальше, я был на: http://code.activestate.com/recipes/576507-sort-strings-containing-german-umlauts-in-correct-/

UPDATE

Хорошо, так что если вы хотите сохранить свой метод и избавиться от умлаутов, вы можете сделать что-то подобное, есть множество способов сделать это лучше, но это только начало:

import locale
locale.setlocale(locale.LC_ALL, "")

lst = ['Zabel', 'Schneider', 'anabel', 'Arachno', 'Öztürk', 'de Hahn']

def _human_key(your_list):
    your_list.sort(key=locale.strxfrm)
    res = []
    for item in your_list:
        word = item.replace("Ä", "A").replace("Ö", "O").replace("Ü", "U")\
              .replace("ä", "a").replace("ö", "o").replace("ü", "u")\
              .replace("ß", "s")
        res.append(word)
    return res

print(_human_key(lst))

дал мне:

['anabel', 'Arachno', 'de Hahn', 'Ozturk', 'Schneider', 'Zabel']

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

0 голосов
/ 21 марта 2019

Если вы не возражаете против использования сторонних модулей, вы можете использовать natsort (полное раскрытие, я автор). Для данных, которые вы предоставляете, он возвращает то, что вы хотите из коробки.

>>> from natsort import natsorted, ns
>>> data = ['Zabel', 'Schneider', 'anabel', 'Arachno', 'Öztürk', 'de Hahn']
>>> natsorted(data, alg=ns.LOCALE)  # ns.LOCALE turns on locale-aware handling
['anabel', 'Arachno', 'de Hahn', 'Öztürk', 'Schneider', 'Zabel']
>>> from natsort import humansorted
>>> humansorted(data)  # shortcut for using LOCALE
['anabel', 'Arachno', 'de Hahn', 'Öztürk', 'Schneider', 'Zabel']

Если вам нужен ключ сортировки, вы можете использовать генератор ключей natsort:

>>> from natsort import natsort_keygen, ns
>>> humansort_key = natsort_keygen(alg=ns.LOCALE)
>>> humansort_key(this) < humansort_key(that)

Обратите внимание, вам не обязательно использовать локаль ... вам просто нужно правильно нормализовать юникод, что автоматически делает natsort под капотом. В вашем случае, похоже, вы хотите, чтобы заглавные и строчные буквы сгруппировались вместе со строчными в первую очередь, поэтому вы можете использовать это вместо

>>> natsorted(data, alg=ns.GROUPLETTERS | ns.LOWERCASEFIRST)  # or ns.G | ns.LF
['anabel', 'Arachno', 'de Hahn', 'Öztürk', 'Schneider', 'Zabel']

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

...