Шаг 23.
Python: сборник рецептов.
Строки и текст. Разрезание строк различными разделителями

    На этом шаге мы рассмотрим метод re.split().

Задача

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

Решение

    Функция split() на строковом объекте предназначена для очень простых случаев: не допускает использования нескольких разделителей и не учитывает возможные пробелы вокруг разделителей. В случаях когда вам нужно немного больше гибкости, используйте метод re.split():

>>> line = 'asdf fjdk; afed, fjek,asdf,      foo'
>>> import re
>>> re.split(r'[;,\s]\s*', line)
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
>>> 


Обсуждение

    Функция re.split() будет в этом случае весьма полезной, поскольку вы сможете определить многочисленные шаблоны разделителей. Например, как показано в решении, разделитель может быть запятой (,), точкой с запятой (;) или пробелом, за которым следует любое количество дополнительных пробелов. Какой бы из этих шаблонов не был найден, совпадение становится разделителем. Результатом будет просто список полей - точно такой же, какой создает строковый метод str.split().

    При применении re.split() вы должны быть осторожными, если шаблон регулярного выражения использует группу, заключенную в скобки. При использовании групп совпавший с шаблоном текст также включается в результат. Например:

>>> fields = re.split(r'(;|,|\s)\s*', line)
>>> fields
['asdf', ' ', 'fjdk', ';', 'afed', ',', 'fjek', ',', 'asdf', ',', 'foo']
>>> 

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

>>> values = fields[::2]
>>> delimiters = fields[1::2] + ['']
>>> values
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
>>> delimiters
[' ', ';', ',', ',', ',', '']
>>> 
>>> # Переформатируем строку, используя те же разделители
>>> ''.join(v+d for v,d in zip(values, delimiters))
'asdf fjdk;afed,fjek,asdf,foo'
>>> 

    Если вы не хотите, чтобы разделители попали в результат, но при этом вам нужно применить группы в шаблоне регулярного выражения, убедитесь, что вы используете незахватывающую (noncapture) группу, которая определяется так: (?:...). Например:

>>> re.split(r'(?:,|;|\s)\s*', line)
['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
>>> 

    На следующем шаге мы рассмотрим поиск текста в начале и в конце строки.




Предыдущий шаг Содержание Следующий шаг