Pull to refresh

Regex и Win cmd, простенький пример

Reading time4 min
Views19K
Заметил, что здесь много сложных и интересных статей про Win cmd и Regex, но гораздо меньше чего-то простого, с чего можно начать знакомство с этими мощными инструментами.
Идея написания этого урока возникла, когда я понял, что наверняка такие же задачи пытается решить еще кто-то и возможно такая статейка поможет кому-нибудь поменять рутинный копи-паст на гораздо более интересный и технологичный метод написания кода.

Итак, вводная:

Небольшой сайт. Вбиваю туда ссылки на изображения, причем в каждую ссылку должна быть вложена миниатюра большого изображения. Т.е., затронем вопросы как автоматически создать список файлов в папке и как быстро добавить список файлов в html код страницы.
Изображения разложил в папочке на локальном диске, но там их много и лень копипастить, да и сколько можно? Внезапно обнаружил, что пальцы уже набирают в комстроке:

dir /b /A:-D> spisok.txt


Dir создаст список файлов, /b оставит только имена файлов и их расширения, /A:-D выведет только файлы, но не папки, > загонит это все в текстовой файл с названием spisok.txt.

Теперь получившийся файл открываем в Notepad++ (хотя можно наверное и в редакторе с аналогичным функционалом), где делаем следующее:

Ctrl+H, открывается окно c закладкой Replace,
Find What:
(.*)\.(.*)

Replace with:
\1

Внизу ставим галочку Regular Expression, а Wrap around и .matches newlin убираем.
Жмем Replace All.
Однако, если в названии файлов содержится не одна тока, то возникнут проблемы. См. конец статьи и комментарии.

Команда, записанная в Find делает следующее:
выбирает в найденной строке все, что до точки, затем ее саму и все после нее. Причем все, что до точки сохраняется под номером 1, а все, что после нее, под номером 2. Мы воспользуемся этим позже.
Далее, команда замещает выбранную строку на то, что записано в Replace with, т.е. на тег ссылки, в котором прописан путь и в который вложен тег картинки c миниатюрой большого изображения.

Теперь, рассмотрим каждую строчку.

(.*)\.(.*)
. — означает найти любой символ
* — означает, взять как можно больше
т.е. «.*» будет означать примерно следующее: найти и выделить как можно больше символов, любых. Т.е. выделить всю строку. И эта команда все и выделит, если бы не:

\. — означает выделить точку.
Однако, точка только что была описана мной как команда, выделяющая любой символ. Дело в том, что Regex использует символ «\» как команду. Эта команда означает одно из двух:
— если за этим символом идет какой-то спецсимвол, который сам используется как команда, то вывести этот символ сам по себе, а не команду. Т.е. «.» он воспримет как «искать любой символ», а «\.» просто как точку. Если ввести просто Бэкслеш «\» то он будет ожидать, что это команда, а двойной бэкслеш «\\» выведет просто сам символ «\».
— если за этим символом идет число, то скопировать сюда то, что было в скобке в поиске (вместо «\1» будет помещено то, что попало в первую слева скобку при поиске, т.е. имя файла до точки, а вместо «\2», то, что во вторую, т.е. расширение файла, и т.д.) — этим мы воспользуемся чуть позже.

Иными словами, если записать это:
(.*)\.(.*)
вот так:
.*\..*,
то результат поиска не изменится, но Notepad++ никак не отметит для себя и для нас то, что он нашел до точки и после нее. Скобки это как маркеры, разделяющие строку, в данном случае на две части.

\1

<img src="putj – это опять кусок просто текста, чтобы закончить тэг <а> и начать тэг , после которого снова вставляется то, что было помещено в скобки при поиске:

\\\1_small\.\2 — где «\\» выводит бэкслэш, нужный в адресе файла, «\1» выводит содержимое первой скобки, «\.» выводит точку, а \2 это содержимое второй скобки.

_small – это просто текст, он вставляется перед точкой. Уменьшенные изображения придется переименовать, чтобы в конце их названия был суффикс _small. Именно для того, чтобы вставить этот _small перед расширением, я и сделал две скобки в поиске, чтобы можно было _small заключить названием файла слева и расширением этого же файла справа.

" alt=" – это опять кусок тэга, атрибут alt, а после него:
="\1">
— где \1 вставляет название файла в атрибут alt, а после него добавляется закрывающий тэг.

Поскольку расширение файла от его имени отделяется всегда только точкой, то ее я «запоминать» не приказываю (т.е. в поиске не заключаю в скобки), но, по сути, можно было бы записать и так:

Find What: (.*)(\.)(.*)
Replace With: \1

Результат будет тот же. Но это выражение гибче, потому, что можно во вторую скобку вписать, например:

[[:s:]] – выделит пробел. Команда поиска будет выглядеть так: (.*)([[:s:]])(.*)
[[:unicode:]] – выделит символ, чей код в юникоде больше 255. Команда поиска будет выглядеть так: (.*)([[:unicode:]])(.*)
[[:punct:]] – выделит один из следующих символов: , " '?!;: # $ % & ( ) * + — / < > = @ [ ] \ ^ _ { } | ~ Команда поиска будет выглядеть так: (.*)([[:punct:]])(.*)

Так можно выделить начало и конец какого-то кода или слова, где посередине расположен соответствующий символ. Но это уже за пределами данной статейки.

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

Ресурсы:

Список Regex команд с примерами.
Описание команды Dir

UPD
Если в названии файлов содержится не одна тока, то возникнут проблемы. Простейшим способом избежать такой сложности будет переименовать файлы так, чтобы там не было точек нигде, кроме расширений (графический редактор с функцией массового переименовывания файлов подойдет).
Более продвинутый вариант предложен в ходе обсуждения этой статьи:
^(.*)\.([^\.]+)$ ©FilimoniC
Выделит все, до последней точки в имени файла. Т.е. до той, которая находится перед расширением.
Еще более сложный пример смотрите в обсуждении от юзера RumataEstora
Tags:
Hubs:
-3
Comments16

Articles