Быстрый способ разделения буквенных и числовых символов в строке python
Я пытаюсь выработать простую функцию для захвата опечаток, например:
"Westminister15"
"Westminister15London"
"23Westminister15London"
после фиксации:
["Westminister", "15"]
["Westminister", "15", "London"]
["23", "Westminister", "15", "London"]
Первая попытка:
def fixate(query):
digit_pattern = re.compile(r'\D')
alpha_pattern = re.compile(r'\d')
digits = filter(None, digit_pattern.split(query))
alphas = filter(None, alpha_pattern.split(query))
print digits
print alphas
результат:
fixate("Westminister15London")
> ['15']
> ['Westminister', 'London']
Однако, я думаю, что это можно было бы сделать более эффективно, и я все равно получаю плохие результаты, когда я пытаюсь что-то вроде:
fixate("Westminister15London England")
> ['15']
> ['Westminister', 'London England']
Очевидно, что он должен заинтриговать London
и England
отдельно, но я чувствую, что моя функция будет полностью исправлена и более простой подход
Этот вопрос несколько эквивалентен этому php question
Ответы
Ответ 1
Проблема в том, что Python re.split()
не разбивается на совпадения нулевой длины. Но вы можете получить желаемый результат с помощью re.findall()
:
>>> re.findall(r"[^\W\d_]+|\d+", "23Westminister15London")
['23', 'Westminister', '15', 'London']
>>> re.findall(r"[^\W\d_]+|\d+", "Westminister15London England")
['Westminister', '15', 'London', 'England']
\d+
соответствует любому числу цифр, [^\W\d_]+
соответствует любому слову.
Ответ 2
Вот другой подход, если вы предпочитаете держаться подальше от регулярных выражений, что иногда может быть громоздким, если вы не достаточно знакомы, чтобы сделать это/изменить его сами:
from itertools import groupby
def split_text(s):
for k, g in groupby(s, str.isalpha):
yield ''.join(g)
print(list(split_text("Westminister15")))
print(list(split_text("Westminister15London")))
print(list(split_text("23Westminister15London")))
print(list(split_text("Westminister15London England")))
возвращает:
['Westminister', '15']
['Westminister', '15', 'London']
['23', 'Westminister', '15', 'London']
['Westminister', '15', 'London', ' ', 'England']
Генератор также может быть легко модифицирован, чтобы при желании никогда не выдавать пробельные строки.
Ответ 3
Вы можете использовать это регулярное выражение вместо своих:
>>> import re
>>> regex = re.compile(r'(\d+|\s+)')
>>> regex.split('Westminister15')
['Westminister', '15', '']
>>> regex.split('Westminister15London England')
['Westminister', '15', 'London', ' ', 'England']
>>>
Затем вам нужно отфильтровать список, удаляющий пустые строки/только пробелы.