выберите все, что не соответствует шаблону - PullRequest
1 голос
/ 07 октября 2019

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

У меня есть файлы, которые имеют такую ​​форму:

(информация об мусоре) имя файла (другой мусор). расширение или [информация об мусоре] имя файла [другой мусор] .extension

Например, один из файлов - [O2CXDR] отчет за январь [77012] .pdf или (XEW7CK) комиссионные с продаж (99723) .xls

Я использую библиотеку regex.h в C, поэтому я считаю, что это библиотека POSIX.

Я надеюсь извлечь "filename" и ".extension", чтобы написатьскрипт, который будет содержать файлы filename.extension

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

\s*(\[|\().*?(\]|\))+\s*

и отрицательный прогноз, который я пробовал, был:

.*(?!(\s*(\[|\().*?(\]|\))+\s*)).*

, но он просто выбирает все в одном совпадении.

Я уверен, что я не понимаю, взглядыи смотреть сзади правильно. Что мне нужно сделать, чтобы исправить свое выражение? Может кто-нибудь объяснить, как они работают, так как я немного растерялся. Спасибо!

Ответы [ 3 ]

1 голос
/ 07 октября 2019
$ cat input_file
(garbage info) filename (other garbage).extension
 (garbage info)filename(other garbage).extension
(garbage info)file name(other garbage).extension
[garbage info] filename [other garbage].extension
 [garbage info]filename[other garbage].extension
[garbage info]file name[other garbage].extension
$ sed -re 's/^\s*(\([^\)]*\)|\[[^]]*\])\s*(.*\S)\s*(\([^\)]*\)|\[[^]]*\])(\..*)$/\2\4/' input_file
filename.extension
filename.extension
file name.extension
filename.extension
filename.extension
file name.extension
1 голос
/ 07 октября 2019

Поскольку вы не указали механизм регулярных выражений, я нацеливаюсь на подмножество, которое может использовать теги \K, \G и \A (например, PCRE ).

В следующем примере используется комбинация сброса совпадений (\K), жадный жадный символ и начало совпадения (без начала строки) \G(?!\A), дальнейшее объяснение приведено ниже:

Смотрите здесь регулярное выражение

Примечание: удалите пустые совпадения

\s*[[(].*?[])]\s*\K|\G(?!\A)(?:(?!\s*[[(].*?[])]\s*).)+
  • Совпадение с одним из следующих:
    • Вариант 1:
      • \s* Соответствует любому пробелу любое количество раз
      • [[(] Соответствует либо [, либо (
      • .*? Соответствиелюбой символ любое количество раз, но как можно меньше (ленивое совпадение)
      • [])] совпадение либо ], либо )
      • \s* совпадение с любым пробелом любое количество раз
      • \K Reset match - устанавливает заданную позицию в регулярном выражении как новый start матча. Это означает, что ничто, предшествующее этому тегу, не будет зафиксировано в общем совпадении.
    • Вариант 2:
      • \G(?!\A) Совпадение только в начальной точке поиска или позициипредыдущего успешного конца матча, но не в начале строки.
      • (?:(?!\s*[[(].*?[])]\s*).)+ Закаленный жадный токен, совпадающий с чем-либо более одного раза, кроме шаблона с отрицательным прогнозом (который совпадает с первым параметром).
1 голос
/ 07 октября 2019

Может быть, так просто, как

^(?:\(([^)]*)\)\s*([^(\r\n]*?)\s*\(([^)]*)\)|\[([^\]]*)\]\s*([^(\r\n]*?)\s*\[([^\]]*)\])\.(.*)$

, мы могли бы извлечь эти значения.

Демонстрация 1

Схема RegEx

jex.im визуализирует регулярные выражения:

enter image description here

Если вам не нужны все эти группы захвата, мы бы просто удалили те, которые нам не нужны:

^(?:\([^)]*\)\s*([^(\r\n]*?)\s*\([^)]*\)|\[[^\]]*\]\s*([^(\r\n]*?)\s*\[[^\]]*\])\.(.*)$

Демо 2

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