Я пытаюсь построить эффективную регулярную регрессию, которая объединяет несколько строк со следующими ограничениями в одну строку.
Положительные образцы:
Пример 1:
My favorite books are as follows:\nA great book\nThe Effective Book onscala.io\nTest Book\n
Матчи:
My favorite books are as follows:\nA great book\nThe Effective Book onscala.io\nTest Book\n
Пример 2:
My favorite books are as follows:\nA great book\nanother sentence\nAnother book\n
Соответствует: строки до тех пор, пока первая буква каждой строки не станет заглавной.
My favorite books are as follows:\nA great book\n
Отрицательный образец:
My favorite books are as follows:\na great book\nanother sentence\n
Не соответствует
Я создал следующее регулярное выражение, но оно соответствует каждой строке независимо от того, начинается ли она с заглавной буквы.
(^[A-Z].*:)\n(^[A-Z].+(?:\s+[a-zA-Z0-9,./ ]+){1,10})
Если бы приведенное выше регулярное выражение соответствовало ожидаемым строкам, я бы заменил \n
пробелом и запятой.
Вы можете использовать это регулярное выражение для получения совпадений:
^[A-Z][^:\n]*:\n(?:[A-Z][\w,./-]*(?:\h+[\w,./-]+){0,9}\n)+
Детали регулярного выражения:
^
: начать новую строку.[A-Z]
: Сопоставьте заглавную букву.[^:\n]*
: сопоставьте 0 или более символов, кроме :
.:\n
: совпадение двоеточия, за которым следует разрыв строки.(?:
: Запустить группу без захвата.
[A-Z][\w,./-]*
: Сопоставьте первое слово, которое должно начинаться с заглавной буквы.(?:\h+[\w,./-]+){0,9}
: Сопоставьте от 0 до 9 других слов, разделенных более чем 1 пробелом.\n
: Сопоставить разрыв строки.)+
: Завершить группу без захвата. Повторите эту группу 1+ раз.Прежде всего используйте этот сайт для тестирования: https://regex101.com/
Это сэкономит вам много времени.
Это должно дать вам то, что вы хотите, хотя вам нужно убедиться, что вы не используете многострочный флаг, чтобы он не соответствовал вашему отрицательному регистру.
^([A-Z](.*\h?){0,9}\n?)+
Вы можете заменить .*
более ограниченным шаблоном для одной строки (исключая первый символ), например:
^(([A-Z])([\w:.,-]*\h?){0,9}\n?)+
Здесь важно то, что вам нужно начальное совпадение, но вам также нужно совпадение n, чтобы убедиться, что вы частично соответствуете своему отрицательному регистру. Я добавил \h
, чтобы соответствовать только табуляциям и пробелам, но не новым строкам.
Вот демо
Самые большие проблемы с вашим регулярным выражением:
m
. Это потому, что он будет соответствовать только началу всей строки, если вы не укажете ему, чтобы он соответствовал началу каждой строки (это то, что означает многострочный аспект)..+(?:\s+[a-zA-Z0-9,./ ]+)
это излишне и на самом деле не дает вам того, что вы думаете. .+
по сути соответствует всей строке, кроме последнего слова (в зависимости от пробела), а затем соответствует [a-zA-Z0-9,./ ]
последнему слову или символу, а затем повторяется в течение 15 строк.Проблема 2 не так уж и плоха, потому что по большей части она делает то, что вы хотите, но то, что я предлагаю, должно быть достаточно скудным, чтобы вы могли на его основе построить и столкнуться с проблемами позже. Опять же, вы можете использовать исходное регулярное выражение, если удалить второе ^
, но я думаю, что что-то может испортиться, потому что в нем много ненужных вещей.