101 СПОСОБ  ЗАРАБОТАТЬ   НА ПЕЧАТИ

Два загадочных режима GREP-поиска

  • Михаил Иванюшин
  • 13 ноября 2024 г.
  • 1322
Если вы при работе в индизайне используете GREP-поиск, то в списке опций поиска наверняка видели режимы со странными названиями «однострочный поиск» и «многострочный поиск». Странными — потому что эти названия совсем не просто соотнести с действиями, выполняемыми при выборе данных режимов. В результате далеко не все пользователи используют эти интересные возможности поиска.

Режимы однострочный (Single-line) и многострочный (Multiline)

Да, в индизайне эти сходные по написанию слова пишутся по-английски именно так: одно слово с дефисом, второе слитно.

При знакомстве с этой опцией может возникнуть непонимание. Первое предположение наличия двух режимов — однострочного и многострочного — используется или первый, или второй. Но на самом деле эти режимы не являются взаимоисключающими: они используются одновременно, и каждый из них или включён, или выключен, у них разные области действия.

Состояние режима «однострочный» влияет на обработку метасимвола . («точка» — совпадение с любым символом). Режим «многострочный» определяет обработку маркеров положения: ^ (начало абзаца) и $ (конец ­абзаца).

Когда однострочный режим выключён, поиск с использованием метасимвола . (точка) выполняется в пространстве абзаца, в котором стоит курсор. Аналогия — каждый абзац в статье является отдельной строкой. Когда однострочный режим активен, поиск с использованием метасимвола . (точка) выполняется в пространстве всей статьи. Статья превращается в одну ­строку.

Однострочный режим

(?-s) однострочный режим выключен, это стандартное состояние обработки греп-запросов: оператор .* выбирает все символы, начиная от текущей позиции до конца абзаца, но сам конец абзаца в выборку не попадает.

(?s) одиночный режим включён, в выборку попадает и знак перевода строки. Т. е. будет выбран весь текст от точки курсора до конца статьи. А если курсор не в тексте, а выбран фрейм, то будет выбрана вся статья.

Важно: если в тексте запроса нет метасимвола точка, то не имеет значения, какой вариант однострочного режима сейчас установлен.

Многострочный режим

(?m) многострочный режим включён, это стандартное состояние обработки греп-запросов, знаки ^ и $ определяют начало и конец абзаца.

(?-m) многострочный режим выключен, знак ^ интерпретируется как \A — маркер начала статьи, а знак $ как \Z — маркер конца статьи.

Важно: если в тексте запроса нет метасимволов ^ и $, то не имеет значения, какой вариант многострочного режима сейчас установлен.

Совместное использование режимов

Если в тексте запроса есть точка и хотя бы один из двух знаков ^ или $, то можно определить, как эти режимы будут взаимо­действовать.

Очевидно, что возможны четыре их сочетания

Два загадочных режима GREP-поиска

Допустим, есть такие запросы поиска .{10}$ и ^.{12} и вот такой текст:

123456789ABCDEF

123456789ABCDEF

12345678

123456789ABCDEF

123456789ABCDEF

Поиск всегда начинается с текущей позиции курсора.

(?s)(?-m).{10}$ Будут выбраны последние десять знаков статьи. Поскольку точка работает как любой знак, то если последним символом статьи будет перевод строки, то он тоже попадёт в выборку.

(?-s)(?-m).{10}$ Если последний знак статьи не является переводом сроки, то будут выбраны последние десять знаков статьи. И т. к. точка работает как печатный знак, то если последним символом статьи будет перевод строки, то ничего выбрано не будет, поскольку среди последних десяти символов есть знак перевода строки, а он не входит в множество знаков, охватываемых метасимволом точка.

(?m)(?-s).{10}$ Будут выбираться последние десять знаков каждой строки. Перевод строки в выборку не входит.

(?sm).{10}$ Если поставить курсор в начало тестового текста, то будут выбираться последние десять знаков каждой строки. Но если, например, поставить курсор после буквы A во второй строке, то запрос выделит следующие десять знаков: буква F, перевод строки и восемь цифр третьей строки. Почему так происходит? Запрос ищет конец абзаца; находит его в конце строки, где он стоит; оценивает число знаков перед этим концом абзаца не только на предмет, есть ли нужное число, но и где находится текущая точка вставки. В нашем случае точка вставки попадает в эти десять знаков, значит, этот перевод строки не подходит. Он ищет следующий, так же проверяет десять символов перед ним, не попадает ли в них текущая позиция курсора. Если нет, то они выделяются.

В этом примере мы поставили курсор после буквы A. Такой же результат будет до буквы F. Но как только курсор после F, он попадает в пространство десяти знаков перед переводом строки, и запрос ищет в тексте следующий перевод строки.

(?s)(?-m)^.{12} Поиск в статье, ищутся все знаки в тексте. Знак ^ интерпретируется не только как начало абзаца , но и как \r, поэтому этот запрос последовательно выделяет сперва 12 знаков с начала статьи, а потом все последовательности из двенадцати знаков, начинающихся с \r.

(?-s)(?-m)^.{12} Поиск в статье, любой печатный знак. Поскольку «любой печатный знак», т. е. перевод строки в выборку не попадёт, то этот запрос выберет только первые двенадцать символов первой строки, если длина строки больше 12.

(?m)(?-s)^.{12} Поиск в строке, любой печатный знак.

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

(?sm)^.{12} Поиск в строке, любой знак.

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

Конечно, приведённые примеры вряд ли встретятся в реальной вёрстке. Но они полезны для того, чтобы понять особенности использования этих режимов.

Для понимания

Если есть два абзаца

Фраза

Слово

то любой из запросов .+ или (?-s).+ найдёт сперва абзац Фраза, а потом абзац Слово. В выборке будут только печатные знаки.

А если у нас такой запрос (?s).+, то он будет видеть этот текст так, в виде одной строки:

Фраза\rСлово

и этот запрос выберет все знаки в этой строке.

Строки ^фраза и (?m)^фраза обозначают поиск текста фраза в начале любой строки.

Строки слово$ и (?m)слово$ обозначают поиск текста слово в конце любой строки.

Строка (?-m)^фраза обозначает поиск текста фраза в начале статьи. Строка (?-m)слово$ обозначает поиск текста слово в конце статьи. Очевидно, что эти запросы можно переписать иначе, сделав их более понятными: \Aфраза и слово\Z.

Требуется уточнение

В начале было сказано, и это взято из документации, что состояние многострочный режим включено по умолчанию. Вся ли это информация об этом режиме?

Вот задача: найти каждый первый пробел в абзацах и запрос для её решения: ^(.+?)\K\h

Запрос эту задачу не решает, т. к. идёт через строку, и почему он так ведёт себя, я точно не знаю. Возможно, это особенности реализации нежадного поиска. Но если его изменить: (?m)^(.+?)\K\h, то он будет идти по каждой строке.

В чём же дело? Ведь если многострочный режим включён по умолчанию, то запросы ^(.+?)\K\h и (?m)^(.+?)\K\h должны выполняться одинаково. Однако этого не происходит. Моё предположение, что да, это так, но дополнительно при появлении команды (?m) изменяется трактовка знака ^, он становится на время работы запроса не только маркером начала абзаца, но и соответствует переводу строки \r.

Вот как это выглядит в реализации с другими запросами: запрос \r(.+?)\K\h идёт по всем строкам, начиная с второй, а запрос (^|\r)(.+?)\K\h работает так же, как (?m)^(.+?)\K\h. Точно так же будут работать (?s)^(.+?)\K\h и (?-s)^(.+?)\K\h, именно в силу того, что на время действия запроса операторы включения любого из этих режимов определят, что в запросе метасимвол ^ надо трактовать как \r.

Примеры

• Заменить шпации на табуляции.

В тексте позиции списка разделены концевыми шпациями.

A) text, numbers =КШ= D) text, numbers

B) text, numbers =КШ= E) text, numbers

C) text, numbers =КШ= F) text, numbers

Тут =КШ= — текстовое обозначение концевой шпации.

Надо заменить эти шпации на табуляции.

Запрос ^\u\).+\K~f будет искать через строку.

А явное указание, что многострочный режим включён (хотя он уже был включён по умолчанию), определит на время действия запроса, что символ начала статьи/начала абзаца ^ надо применять и к переводу строки. В результате запрос (?m)^\u\).+\K~f пройдёт по каждой строке.

• Выделить весь текст статьи, независимо от того, где стоит курсор.

Запрос .* выделит текст от текущей позиции до конца абзаца. Поскольку в запросе есть точка, то для расширения области действия запроса надо использовать однострочный режим. От текущей позиции до конца абзаца статьи текст выделит такой запрос (?s).*, а задачу выделения всего текста статьи решит запрос (?s)\A.+ В обоих случаях именно включение однострочного режима позволило включить в выборку знаки перевода строки.

• Выделить текст от позиции курсора до конца статьи.

Задачу выделения текста от позиции курсора до конца статьи решает любой из таких запросов:

(.|[\r\n])+ или (?s).*

Первый вариант для стандартного случая, когда однострочный режим выключен. Второй включает этот режим, и вся статья для поиска .* становится одной строкой.

Заключение

К сожалению, к тому диалекту GREP, что есть в индизайне, на русском языке нет толковой информации от разработчиков. Данная статья — результат моего исследования этих режимов. Когда с ними разобрался, многие задачи поиска стали решаться намного проще.

Попробуйте и вы сделать их своим инструментом, если пока не получалось использовать эти режимы.

Будут вопросы, пишите.

Михаил Иванюшин, независимый автор.

dotextok@gmail.com

https://dotextok.ru

ПОХОЖИЕ СТАТЬИ
Тренды в дизайне в 2026 году

12 февраля в творческом пространстве «Мойка-8» Союза дизайнеров Санкт-Петербурга компания «Берег» провела день открытых дверей своего проекта «Образовательная среда на Берегу». Семинары «Среды» давно известны и любимы в кругах петербургских полиграфистов, поэтому на Мойке был полный аншлаг.

Генеративный ИИ для полиграфии: волшебная палочка или миф?

С ростом возможностей и популярности генеративных визуальных моделей (нейросетей) множатся и мифы вокруг них. При этом чем ниже осведомлённость в вопросе, тем выше ожидания.

Полиграфический музей в Северной столице

Publish продолжает серию публикаций о музеях, связанных с полиграфией. Первые статьи рассказывали о московских организациях: Музее истории полиграфии, книгоиздания и МГУП имени Ивана Фёдорова (Publish № 2, 2025), Музее-квартире И. Д. Сытина (Publish № 4, 2025) и Музее «Подпольная типография 1905–1906 гг.» (Publish № 7, 2025). Продолжал тему Мемориальный Дом-музей «Подпольная типография Пермского комитета РСДРП 1906 года» в Перми (Publish № 9, 2025) и Музей провинциального печатного и издательского дела. На очереди — Санкт-Петербург.

Чёртова дюжина вопросов про лазерную высечку

За прошедшие 5–6 лет многие предприятия диверсифицировали свой бизнес, начав развивать направление малотиражной этикетки и упаковки. Но по мере его роста им требуются более производительные устройства не только для печати, но и для резки. Одним из них может послужить рулонная лазерная высечка. На ряд очевидных и при этом важных для понимания возможностей этого типа оборудования вопросов отвечает директор по развитию «НИССА Центрум» Михаил Кувшинов.

Новый инструмент мастера

В мире интерьерного дизайна и рекламного производства всегда ценилась способность сочетать полёт творческой фантазии с передовыми технологиями. Порой расширить границы возможного удаётся с помощью гибридного УФ-принтера.


Реклама. Рекламодатель ООО "ТКС"
erid 2SDnjdV8MgD


Новый номер

Модернизация и восстановление печатных машин. Нюансы покупки восстановленного оборудования. Печать по ткани. Почему рынок текстильной печати не цифровизируется? Рецепты по оживлению рынка от B2PRINT. Путь из маркетплейса в полиграфию. Экспертный взгляд на подарочную упаковку. Многоплановость в цифровом производстве. Чёртова дюжина вопросов про лазерную высечку. Тренды в дизайне в 2026 году. «Цифра» перезагрузит рынок книжной и коммерческой печати. Полиграфический музей в Северной столице.



Какой следующий принтер вы купите себе на производство?
Широкий УФ
25%
25 %
Сувенирный УФ
27%
27 %
ДТФ (текстиль)
20%
20 %
УФ ДТФ
20%
20 %
Латекс
7%
7 %
Экосольвент
12%
12 %
На водных чернилах
7%
7 %
Сублимацию
8%
8 %
Для прямой печати по ткани
10%
10 %
ДТГ («футболочный»)
3%
3 %
Проголосовало: 59