#python #regex
#python #регулярное выражение
Вопрос:
Для извлечения первых трех букв «abc» и трех наборов трехзначных чисел в 000_111_222
я использую следующее выражение:
text = 'abc_000_111_222'
print re.findall('^[a-z]{3}_[0-9]{3}_[0-9]{3}_[0-9]{3}', text)
Но выражение возвращает пустой список, когда вместо подчеркивания вместо этого используются минусы или точки: abc.000.111.222
или abc-000-111-222
или любая их комбинация, например: abc_000.111-222
Конечно, я мог бы использовать простой метод замены для унификации текстовой переменной text=text.replace('-','_').replace('.','_')
Но мне интересно, мог бы я вместо замены изменить выражение регулярных выражений, которое распознавало бы подчеркивания, минусы и точки.
Комментарии:
1. Заменить символ подчеркивания на что-то, что соответствует любому из трех символов?
2. еще несколько примеров строк прольют больше света на то, чего вы пытаетесь достичь
3.
print re.findall(r'^[a-z]{3}(?:[_.-]d{3}){3}$', text)
должно работать4. @anubhava, шаблон можно повторить только дважды, так как строка не заканчивается на
_
5. Нет,
_
перед первым номером также есть.
Ответ №1:
Вы можете использовать классы символов регулярных выражений с [
… ]
. В вашем случае это может быть [_.-]
(обратите внимание на дефис в конце, если его нет в конце, он будет рассматриваться как диапазон, подобный [a-z]
).
Вы можете использовать регулярное выражение следующим образом:
print re.findall('^[a-z]{3}[_.-][0-9]{3}[_.-][0-9]{3}[_.-][0-9]{3}', text)
Кстати, вы можете сократить свое регулярное выражение, чтобы получить что-то вроде этого:
print re.findall('^[a-z]{3}[_.-](d{3}[_.-]){2}d{3}', text)
Просто в качестве комментария, если вы хотите сопоставить один и тот же разделитель, вы можете использовать группы захвата и ссылаться на его содержимое следующим образом:
^[a-z]{3}([_.-])[0-9]{3}1[0-9]{3}1[0-9]{3}
Комментарии:
1. Потрясающий ответ! Спасибо!
2. @буквенно-цифровой рад помочь
Ответ №2:
Почему бы не отказаться regexes
вообще и использовать более понятное и простое решение?
$ cat /tmp/tmp.py
SEP = '_.,;-= '
def split_str(text):
for s in list(SEP):
res = text.split(s)
if len(res) > 1:
return text.split(s)
print(split_str('abc_000_111_222'))
print(split_str('abc;000;111;222'))
print(split_str('abc.000.111.222'))
print(split_str('abc-000-111-222'))
Что дает:
$ python3 /tmp/tmp.py
['abc', '000', '111', '222']
['abc', '000', '111', '222']
['abc', '000', '111', '222']
['abc', '000', '111', '222']
$