У меня возникли некоторые проблемы с тем, чтобы регулярное выражение Python работало при сопоставлении текста, который занимает несколько строк. Пример текста ('\ n' - это новая строка)
some Varying TEXT\n
\n
DSJFKDAFJKDAFJDSAKFJADSFLKDLAFKDSAF\n
[more of the above, ending with a newline]\n
[yep, there is a variable number of lines here]\n
\n
(repeat the above a few hundred times).
Я хотел бы зафиксировать две вещи: часть some_Varying_TEXT и все строки текста в верхнем регистре, которые идут двумя строками ниже, за один захват (я могу вырезать символы новой строки позже). Я пробовал несколько подходов:
re.compile(r"^>(\w+)$$([.$]+)^$", re.MULTILINE) # try to capture both parts
re.compile(r"(^[^>][\w\s]+)$", re.MULTILINE|re.DOTALL) # just textlines
и множество его вариаций безуспешно. Последний, кажется, соответствует строкам текста одну за другой, что мне не очень нужно. Я могу уловить первую часть, без проблем, но я не могу уловить 4-5 строк текста в верхнем регистре. Я бы хотел, чтобы match.group (1) была some_Varying_Text, а группа (2) была line1 + line2 + line3 + и т.д., пока не встретится пустая строка.
Если кому-то интересно, это должна быть последовательность аминокислот, из которых состоит белок.
>
символа. Должен ли он?Ответы:
Попробуй это:
Я думаю , что самой большой проблемой является то , что вы ожидая
^
и$
якоря , чтобы соответствовать символы новой строки, но они этого не делают. В многострочном режиме^
сопоставляет позицию сразу после новой строки и$
соответствует позиции, непосредственно предшествующей новой строке.Также помните, что новая строка может состоять из перевода строки (\ n), возврата каретки (\ r) или возврата каретки + перевода строки (\ r \ n). Если вы не уверены, что ваш целевой текст использует только перевод строки, вам следует использовать эту более инклюзивную версию регулярного выражения:
Кстати, вы не хотите использовать здесь модификатор DOTALL; вы полагаетесь на то, что точка соответствует всему, кроме новой строки.
источник
Это будет работать:
Некоторое объяснение этого регулярного выражения может быть полезно:
^(.+?)\n\n((?:[A-Z]+\n)+)
^
) означает «начало с начала строки». Имейте в виду, что он не соответствует самой новой строке (то же самое для $: это означает «непосредственно перед новой строкой», но не соответствует самой новой строке).(.+?)\n\n
означает «сопоставить как можно меньше символов (разрешены все символы), пока не дойдете до двух символов новой строки». Результат (без символов новой строки) помещается в первую группу.[A-Z]+\n
означает «сопоставьте как можно больше букв в верхнем регистре, пока не дойдете до новой строки. Это определяет то, что я буду называть текстовой строкой .((?:
Текстовая строка)+)
означает соответствие одной или нескольким текстовым строкам, но не помещает каждую строку в группу. Вместо этого поместите все в объекты TextLine в одной группы.\n
в регулярное выражение, если хотите, чтобы в конце был двойной символ новой строки.\n
или\r
или\r\n
), просто исправьте регулярное выражение, заменив каждое вхождение\n
на(?:\n|\r\n?)
.источник
Если бы в каждом файле была только одна последовательность аминокислот, я бы вообще не использовал регулярные выражения. Примерно так:
источник
найти:
\ 1 = некоторый_переменный_текст
\ 2 = строки всех CAPS
Изменить (доказательство того, что это работает):
источник
Ниже приводится регулярное выражение, соответствующее многострочному блоку текста:
источник
Мои предпочтения.
На данный момент у вас есть someVaryingText в виде строки и кислоты в виде списка строк. Можно вообще
"".join( acids )
сделать одну струну.Я считаю это менее неприятным (и более гибким), чем многострочные регулярные выражения.
источник