Как извлечь строку между числами? (И сохранить первый номер в строке?) - PullRequest
2 голосов
/ 04 октября 2019

Я пытаюсь извлечь данные из журнала изменений, используя RegEx. Вот пример структуры журнала изменений:

96545
this is some changes in the ticket
some new version: x.x.22
another change
new version: x.y.2.2
120091
this is some changes in the ticket
some new version: z.z.22
another change
another change
another change
new version: z.y.2.2
120092
...
...
...
  • Каждая точка данных начинается с идентификатора, который имеет диапазон от 5 до 6 цифр.
  • Кроме того, в журнале есть переменное количество изменений (строк) для каждого идентификатора.
  • Каждая точка данных заканчивается на new version: ***. *** - это строка, которая является переменной для каждого идентификатора.

Я использовал RegExStrom Tester , чтобы проверить мой RegEx.

Пока у меня есть: ^\w{5,6}(.|\n)*?\d{5,6} однако результат включает в себя идентификатор из следующего билета, который мне нужно избегать.

Результат:

96545
this is some changes in the ticket
some new version: x.x.22
another change
new version: x.y.2.2
120091 

Ожидаемый результат:

96545
this is some changes in the ticket
some new version: x.x.22
another change
new version: x.y.2.2

Ответы [ 4 ]

3 голосов
/ 04 октября 2019

Захватывает каждый идентификатор записи в группе 1 и содержимое в группе 2

r'(?ms)^(\d{5,6}\r?\n)(.*?)^new version:'

https://regex101.com/r/A3ejjN/1

1 голос
/ 05 октября 2019

Если проблема заключалась в том, что вы захватили идентификатор следующего билета, просто используйте положительный взгляд вперед, чтобы обработать его, но не захватить его или потреблять его:

# end of tickets is the end of line that the line after it contains the Id of the next ticket
pattern = r"\d{5,6}[\s\S]*?(?=\n\d{5,6})"

# to extract first ticket info just use search
print(re.search(pattern, text).group(0))

# to extract all tickets info in a list use findall
print(re.findall(pattern, text))

# if the file is to big and you want to extract tickets in lazy mode
for ticket in re.finditer(pattern,text):
    print(ticket.group(0))
1 голос
/ 04 октября 2019

Ваше регулярное выражение близко. Его проблема в том, что он «заканчивается» в начале следующего журнала, используя \d{5,6}, чтобы отметить конец записи в журнале (и сопоставить его в процессе). Как упоминал Виктор, было бы более разумно использовать «новую версию» в качестве разделителя, поэтому я сделал это здесь.

found_matches = re.findall("(^\d{5,6}[\s\S]*?^new version: .*$)", log_file_content, re.MULTILINE)

Регулярное выражение (^\d{5,6}[\s\S]*?^new version: .*$) ищет 5или 6 цифр в начале строки, а затем принимает любой символ (включая символы новой строки) вплоть до первого экземпляра new version:, который появляется в начале строки. Затем он читает до конца строки, чтобы завершить эту группу. Так как вы собираетесь сопоставлять символы новой строки, обязательно запомните аргумент re.MULTILINE!

Проверьте регулярное выражение здесь и полный код Python здесь .

1 голос
/ 04 октября 2019

Это будет сделано:

^\d{5,6}[\r\n]*.*?^new version:[^\r\n]*

Просто убедитесь, что флаги MULTILINE и DOTALL включены с помощью re.MULTILINE | re.DOTALL

https://regex101.com/r/YeIUQx/1

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...