Регулярное выражение для извлечения всех возможных комбинаций символов между группами ключей

#python #regex

#python #регулярное выражение

Вопрос:

Я борюсь с проблемой регулярных выражений: У меня есть строка, подобная этой:

 number I need is 1234, but I also need 5678, and 9123 too...
 

Что я хочу сделать, так это получить все возможные группы до 50 символов между словом «число» и четырьмя цифрами:

 Group1: number I need is 1234

Group2: number I need is 1234, but I also need 5678

Group3: number I need is 1234, but I also need 5678, and 9123
 

Я пытаюсь с:

 number.{0,50}d{4}
 

что дает

 number I need is 1234, but I also need 5678, and 9123
 

а также попытка с:

 number.{0,50}?d{4}
 

который получает только:

 number I need is 1234
 

Я мог бы решить это с помощью цикла for, в котором я удаляю найденный текст при каждой новой итерации, но мне интересно, есть ли для этого уникальное регулярное выражение.

Большое вам спасибо!

Комментарии:

1. Пожалуйста, отформатируйте свой вопрос так, чтобы его можно было понять. Добавьте строку примера.

2. Здравствуйте, я уже это сказал: мне нужно число 1234, но мне также нужно 5678 и 9123 тоже…

3. Как вы получаете 5678 из строки, которая содержит литерал 1234 ?

4. Строка Mu содержит как 1234, так и 5678: я хотел бы извлечь обе подстроки из «number» в «1234» (я уже это делаю), а также из «number» в «5678», как я указал в исходном сообщении. Итак, моим результатом должна быть группа, состоящая из: нужное мне число равно 1234; а также группа, состоящая из: нужное мне число равно 1234, но мне также нужно 5678. Я надеюсь, что теперь все понятно.

5. Пожалуйста, укажите фактическую строку примера и то, что вы хотите извлечь из нее.

Ответ №1:

Вероятно, самый чистый способ — использовать цикл, который добавляет к шаблону:

 import re 

s='number I need is 1234, but I also need 5678, and 9123 too...'


pat=r'(number.{0,50}?dddd'
addition=r'.{0,50}?dddd'
while m:=re.search(pat ')', s):
    print(m.group(1))
    pat =addition
 

С принтами:

 number I need is 1234
number I need is 1234, but I also need 5678
number I need is 1234, but I also need 5678, and 9123
 

Комментарии:

1. Большое вам спасибо за ваш ответ. На самом деле я думал о цикле for, но мне также было интересно, можно ли решить такую проблему с помощью одного регулярного выражения.

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

3. Хорошо, еще раз спасибо за вашу помощь. Тогда для меня этого достаточно

Ответ №2:

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

 number(?:.{0,50}?d{4}) 
 
  • number Совпадение буквально
  • (?: Нет группы захвата
    • .{0,50}?d{4} Сопоставьте любой символ 0-50 раз, не жадный, затем сопоставьте 4 цифры
  • ) Закройте группу и повторите 1 раз, чтобы соответствовать хотя бы одному вхождению

Демонстрация регулярных выражений | Демонстрация Python

Например

 import re

s = "number I need is 1234, but I also need 5678, and 9123 too..."
pattern = r"number(?:.{0,50}?d{4}) "
res = ""
m = re.search(pattern, s)
if m:
    for s in filter(None, re.split(r"(?<=d{4})", m.group())):
        res  = s
        print(res)
 

Вывод

 number I need is 1234
number I need is 1234, but I also need 5678
number I need is 1234, but I also need 5678, and 9123
 

Комментарии:

1. Элегантное решение, я не знал, какой шаблон разделения вы использовали.