Regex python - соответствует новой строке, только если за ней следует число или специальный символ и пробел - PullRequest
0 голосов
/ 03 февраля 2020

Я пытался выяснить это регулярное выражение в Python, но он не дает ожидаемого результата.

У меня есть текстовый файл, который я загружаю, в формате:

"18 75 19\n!dont split here\n! but split here\n* and split here"

Я хотел бы получить следующий вывод:

['18 75 19\n!dont split here',
 '! but split here',
 '* and split here']

Я пытаюсь разделить мою строку либо 1) новой строкой, за которой следует число, либо 2) новой строка, за которой следует специальный символ , только если за ним следует пробел (например, «! но разделить здесь», но не «! не разделять здесь»).

Вот что у меня так далеко:

re.split(u'\n(?=[0-9]|([`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,./<>?])(?= ))', str)

Это близко, но еще не там. Вот результат, который он выдает:

['18 75 19\n!dont split here', '!', '! but split here', '*', '* and split here']

Он неправильно соответствует специальному символу отдельно: '!' и '*' имеют свой собственный элемент. В регулярном выражении есть два оператора предпросмотра.

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

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

Спасибо!

1 Ответ

4 голосов
/ 03 февраля 2020

Ваше регулярное выражение на самом деле работает, проблема в группе захвата, которую вы имеете около [`\-=~!@#$%^&*()_+\[\]{};\'\\:"|<,./<>?]. Из руководства :

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

Если вы удалите () вокруг этого класса символов, вы получите ожидаемые результаты.

Обратите внимание, что вам не нужно (?= ) в этом чередовании, поскольку оно уже является частью смотрите, вы можете просто использовать (пробел). Также вам может быть проще написать символы как класс отрицанных символов, например

re.split(u'\n(?=[0-9]|[^A-Za-z0-9] )', str)
...