Как и в других редакторах, в Emacs есть команды для поиска случаев появления какой-нибудь строки. Основная команда поиска необычна тем, что она является наращиваемой; она начинает поиск до того, как вы закончили набор строки поиска. Существуют также команды и для ненаращиваемого поиска, более похожие на аналогичные команды в других редакторах.
Кроме обычной команды replace-string, которая находит все
случаи появления одной строки и заменяет их другой, Emacs имеет более
сложную команду замены, названную query-replace, которая
запрашивает в интерактивном режиме, в каких случаях надо произвести
замену.
набрали) может быть найдена. Когда вы набрали достаточно знаков, чтобы определить желаемое место, вы можете остановиться. В зависимости от того, что вы собираетесь делать потом, вам может понадобиться, а может и не понадобиться прекратить поиск явно с помощью RET.
isearch-forward).
isearch-backward).
C-s начинает наращиваемый поиск. C-s считывает знаки с клавиатуры и располагает курсор в первом месте появления знаков, которые вы набрали. Если вы наберете C-s и затем F, то курсор встанет справа после первой найденной `F'. Наберите О, и увидите, что курсор встал за первой найденной `FO'. После еще одной О курсор встанет за первой `FOO' каждом шаге в эхо-области.
Если вы сделали ошибку в наборе строки поиска, то вы можете сбросить знаки с помощью DEL. Каждый DEL либо нет. Если же вы не хотите ждать, пока это произойдет, используйте C-g так, как описано ниже.
Когда вы будете удовлетворены достигнутым местом, вы можете набрать RET образом, набор C-a привел бы к выходу из поиска и затем передвинул бы курсор в начало строки. RET необходим только в том случае, если следующая команда, которую вы хотите набрать, является печатным знаком, DEL, RET или другим управляющим знаком, имеющим особое значение во время работы поиска (C-q, C-w, C-r, C-s, C-y, M-y, M-r или M-s).
Иногда вы ищете слово `FOO' и находите его, но это не то, что вам нужно. Было второе `FOO', о котором вы забыли, находящееся перед тем, которое вы ищете. В этом случае наберите C-s еще раз, чтобы продвинуться к следующему появлению строки поиска. Это можно проделывать неограниченное число раз. Если вы проскочили, то можете отменить некоторые число знаков C-s с помощью DEL.
После выхода из поиска вы можете снова искать ту же самую строку, просто набрав C-s C-s: первый C-s -- это ключ, который запускает наращиваемый поиск, а второй C-s означает "повтор поиска".
Чтобы вы могли снова использовать более ранние строки поиска, существует список поиска. Команды M-p и M-n редактирования и начала поиска наберите C-s или C-r.
Если ваша строка вообще не найдена, то эхо-область говорит `Failing I-Search'. Курсор располагается после того места, где Emacs нашел из вашей строки всс, что смог. Таким образом, если вы ищете `FOOT', а такой строки нет, вы можете увидеть курсор после `FOO' в слове `FOOL'. С этого места вы можете сделать несколько вещей. Если ваша строка неправильно набрана, вы можете что-то стереть из нее и исправить. Если вы довольны найденным местом, вы можете набрать RET или любую другую команду Emacs, чтобы "принять то, что предложил этот поиск", или вы можете набрать C-g, что уничтожит из строки поиска знаки, которые не были найдены (`Т' в `FOOT'), оставляя те, что нашлись (`FOO' в `FOOT'). Второй C-g в этом месте отменяет поиск полностью, возвращая точку туда, где она была, когда поиск начался.
Если строка поиска содержит заглавную букву, то поиск производится с учетом регистра. Если вы удалите заглавные буквы из строки поиска, эта особенность исчезает. Смотрите раздел Поиск и регистр букв.
Если поиск был неудачным и вы просите повторить его, набирая C-s еще раз, то он начинается снова с начала буфера. Повторение неудачного поиска в обратном направлении при помощи команды C-r начинает новый поиск с конца. Такой поиск называется круговым. Как только это произошло, в подсказке поиска появляется слово `Wrapped'. Если вы пройдете через точку, где начался поиск, это слово заменяется на `Overwrapped', что означает, что вы снова проходите через уже виденные вами совпадения.
Знак "выхода" C-g поступает во время поиска особым образом. Что именно он делает, зависит от статуса поиска. Если поиск нашел то, что вы хотели, и ожидает ввода, то C-g полностью отменяет поиск. Курсор возвращается туда, откуда вы начали поиск. Если C-g успешным, и он ждет дальнейшего ввода, таким образом, второй C-g отменит поиск полностью.
Чтобы найти символ перевода строки, введите C-j. Для поиска другого управляющего знака, такого как control-S или возврат каретки, вы должны отменить их специальное значение, набирая перед ними C-q. Эта функция C-q аналогична ее назначению как команды для вставки (смотрите раздел Вставка текста): она заставляет трактовать следующий знак так, как в этом контексте трактовался бы любой "обычный" знак. Вы также можете задать знак по его восьмиричному коду: введите C-q и затем последовательность восьмиричных цифр.
Вы можете изменить направление поиска на обратное при помощи C-r. Вам следует поступить так, если поиск оказался неудачным, потому что место, с которого вы его начали, находилось слишком близко к концу файла. Повторение C-r продолжает поиск следующих случаев появления в обратном порядке, а C-s начинает поиск опять вперед. C-r в поиске может быть отменена при помощи DEL.
Если вы заранее знаете, что вам нужно вести поиск в обратном порядке,
то чтобы начать поиск, вы можете использовать C-r вместо
C-s, так как C-r также является ключом, запускающим команду
(isearch-backward
Знаки C-y и C-w могут использоваться в наращиваемом поиске для захвата текста из буфера в строку поиска. Это делает удобным поиск другого случая появления того текста, который находится в точке. C-w копирует слово после точки в строку поиска, продвигая точку вперед через это слово. Следующая команда C-s для повторения поиска будет затем искать строку, включающую это слово. C-y подобна C-w, только копирует в строку поиска весь остаток текущей строки. И C-y, и C-w преобразуют копируемый текст к нижнему регистру, если поиск сейчас ведется без учета регистра; таким образом поиск остается регистронезависимым.
Команда M-y копирует в строку поиска текст из списка уничтожений. Она использует тот же текст, который был бы восстановлен командой C-y. Смотрите раздел Восстановление.
Когда вы выходите из наращиваемого поиска, метка устанавливается в то место, где точка была до начала поиска. Это удобно для возврата к этому месту. В режиме Transient Mark наращиваемый поиск устанавливает метку, не активизируя ее, если только метка уже не активна.
Чтобы настроить специальные знаки, которые понимает наращиваемый
поиск, измените их привязки в таблице ключей isearch-mode-map.
Для получения перечня привязок посмотрите документацию на
isearch-mode с помощью C-h f isearch-mode RET.
которого добрался поиск, он создает новое окно, состоящее из одиночной строки, и использует его для показа найденной строки. Это окно из одной строки вступает в игру, как только точка выходит за пределы текста, который уже находится на экране.
Когда вы прерываете поиск, однострочное окно убирается. Только в этот момент Emacs перерисовывает окно, в котором производился поиск, чтобы отобразить новое положение точки.
Такой стиль отображения используется, когда скорость терминала в бодах
меньше или равна значению переменной search-slow-speed, чье
начальное значение равно 1200.
Количество строк, показываемых при поиске на медленном терминале,
управляется переменной search-slow-window-lines. Ее обычное
значение равно единице.
В Emacs также есть удобные команды ненаращиваемого поиска, которые требуют от вас полностью набрать строку поиска до начала работы.
Чтобы начать ненаращиваемый поиск, наберите сначала C-s RET. Эта команда входит в минибуфер для считывания строки поиска; ограничьте эту строку с помощью RET, и поиск начнется. Если строка не будет найдена, команда поиска выдает ошибку.
Способ работы C-s RET заключается в следующем: C-s бы бесполезен). C-r RET работает аналогично.
Однако, запрошенный с помощью C-s RET ненаращиваемый поиск
не запускает непосредственно search-forward. Первым делом
проверяется, не будет ли следующим знаком C-w, что запустит поиск
слов.
Прямой и обратный ненаращиваемый поиск осуществляются командами
search-forward и search-backward находить для них подходящие
последовательности ключей.
одиночные пробелы, и эта строка может быть найдена, даже если в оригинале слова разделены несколькими пробелами, переводами строки, либо любыми знаками препинания.
то вы не можете сказать, где прерывается строка в исходом файле. При помощи же поиска слова вы можете искать, не имея этой информации.
Поиск слов -- это специальный случай ненаращиваемого поиска, и он вызывается с помощью C-s RET C-w. За этим следует строка поиска, которая всегда должна быть ограничена RET. Будучи ненаращиваемым, поиск не начинается до тех пор, пока аргумент не завершен. Этот поиск работает путем создания регулярного выражения и его поиска; смотрите раздел Поиск регулярного выражения.
Для обратного поиска слов используйте C-r RET C-w.
Прямой и обратный поиск слов реализован в командах
word-search-forward и word-search-backward подходящие последовательности
ключей.
Регулярное выражение (regexp так и простым.
Наращиваемый поиск регулярного выражения производится набором
C-M-s (isearch-forward-regexp). Эта команда считывает
наращиваемую строку поиска, так же, как C-s регулярное выражение.
Вызов C-s C-M-r (isearch-backward-regexp) или C-r с
префиксным аргументом.
Все управляющие знаки, которые делают специальные вещи в рамках обыкновенного наращиваемого поиска, имеют те же самые функции и в наращиваемом поиске регулярного выражения. Набор C-s или C-r немедленно после начала поиска восстанавливает последнее регулярное выражение, использованное для наращиваемого поиска регулярного выражения; это говорит о том, что наращиваемый поиск регулярного выражения и строки имеют независимые значения по умолчанию. Они также имеют раздельные списки поиска, доступ к которым вы можете получить с помощью M-p и M-n.
Если при наращиваемом поиске регулярного выражения вы наберете SPC, он будет совпадать с произвольной последовательностью пробельных знаков, включая переводы строк. Если вам нужен только один пробел, введите C-q SPC.
Обратите внимание, добавление знаков к регулярному выражению при наращиваемом поиске может вернуть курсор назад и начать поиск снова. Например, если вы искали `foo' и добавляете `\|bar', курсор вернется назад, если первый `bar' предшествовал первому `foo'.
Ненаращиваемый поиск регулярного выражения осуществляется функциями
re-search-forward и re-search-backward. Вы можете
запустить их с помощью M-x, или привязать их к ключам или вызывать
через наращиваемый поиск регулярного выражения с помощью C-M-s
RET и C-M-r RET.
Если вы используете команды наращиваемого поиска регулярного выражения
с префиксным аргументом, они производят обычный поиск строки, как
isearch-forward и isearch-backward. Смотрите раздел Наращиваемый поиск.
Регулярные выражения имеют синтаксис, в котором несколько знаков служат специальными конструкциями, а остальные -- это обыкновенные знаки. Обыкновенный знак -- это простое регулярное выражение, которое соответствует этому знаку и никакому больше. Специальными знаками являются `$', `^', `.', `*', `+', `?', `[', `]' и `\'. Любые другие знаки, появляющиеся в регулярном выражении, являются обыкновенными, если только им не предшествует `\'.
Например, `f' -- это неспециальный знак, значит он обыкновенный, поэтому `f' -- это регулярное выражение, которое соответствует строке `f' и никакой другой. (Оно не соответствует строке `ff'). Аналогично, `о' -- это регулярное выражение, которое соответствует только `о'. (Когда различия в регистре игнорируются, эти регулярные выражения также совпадают с `F' и `O', но мы рассматриваем это как обобщение понятия "та же строка", а не как исключение.)
Любые два регулярных выражения a и b могут быть сцеплены. Результатом является регулярное выражение, совпадающее со строкой, в которой a соответствует некоторому началу этой строки, а b соответствует остатку строки.
В качестве простого примера мы можем сцепить регулярные выражения `f' и `o', чтобы получить регулярное выражение `fo', которое соответствует только строке `fo'. Пока все просто. Чтобы сделать что-то нетривиальное, вам необходимо использовать один из специальных знаков. Здесь представлен их перечень.
grep.
Замечание: для исторической совместимости специальные знаки трактуются как обычные знаки, если они находятся в контексте, в котором их специальный смысл не имеет значения. Например, `*foo' трактует `*' как обыкновенный, так как не существует предыдущего выражения, на которое может подействовать `*'. Плохо быть зависимым от этого правила; лучше всегда явно отменять особый смысл специальных знаков независимо того, где они находятся.
В большинстве случаев `\', за которым следует любой знак, соответствует только этому знаку. Однако, существует несколько исключений: двухзнаковые последовательности, начинающиеся с `\', имеющие особый смысл. Второй знак в такой последовательности всегда обычный, когда встречается сам по себе. Здесь представлена таблица конструкций с `\'.
Конструкции, имеющие отношение к словам и синтаксису, управляются установками в синтаксической таблице (смотрите раздел Синтаксическая таблица).
дать вам возможность отличить пробелы от знаков табуляции. В синтаксисе Лиспа, константная строка начинается и заканчивается двойными кавычками. `\"' обозначает двойные кавычки как часть регулярного выражения, `\\' обозначает обратную косую черту, `\t' обозначает знак табуляции, а `\n' -- знак новой строки.
"[.?!][]\"')]*\\($\\|\t\\| \\)[ \t\n]*"
Здесь последовательно содержатся четыре части: набор знаков, соответствующий точке, `?' или `!' концу строки, табуляции или двум пробелам; и набор знаков, соответствующий любым пробельным знакам, повторяющимся любое число раз.
Чтобы ввести это регулярное выражение интерактивно, вы напечатали бы TAB, чтобы получить знак табуляции, и C-j, чтобы получить знак перевода строки. Вы также печатали бы одиночные обратные косые черты как есть, а не дублировали бы их в соответствии с синтаксисом Лиспа.
Все виды наращиваемого поиска в Emacs обычно игнорируют регистр текста, в котором происходит поиск, если вы задали текст в нижнем регистре. Таким образом, если вы запросили поиск `foo', то совпадениями считаются и `Foo', и `foo' . Регулярные выражения, и в частности наборы знаков, также включаются в это правило: `[aB]' соответствовало бы `a', или `A', или `b' или `B'.
Заглавная буква в любом месте строки наращиваемого поиска делает этот поиск регистрозависимым. Таким образом, поиск `Foo' не найдет `foo' или `FOO'. Это применяется также и к поиску регулярного выражения. Этот эффект исчезает, если вы удалили заглавные буквы из строки поиска.
Если вы установите переменную case-fold-search равной
nil
можете изменить. Смотрите раздел Локальные переменные. Эта переменная
применяется также и к ненаращиваемому поиску, включая те его
разновидности, которые осуществляются командами замены (смотрите раздел Команды замены)
и командами поиска в истории минибуфера (смотрите раздел История минибуфера).
Глобальные команды поиска и замены не нужны в Emacs так часто, как в других редакторах(2), но они доступны. Кроме простой команды M-x replace-string, которая аналогична такой же команде в большинстве редакторов, существует команда M-x query-replace, которая для каждого появления образца спрашивает вас, надо ли его заменять.
выражение) одной строкой замены. Можно выполнить параллельно несколько
замен, используя команду expand-region-abbrevs
(смотрите раздел Управление расшифровкой сокращения).
Чтобы заменить каждый случай вхождения `foo' после точки на `bar', используется команда M-x replace-string с двумя аргументами `foo' и `bar'. Замещение происходит только в тексте после точки, так, если вы хотите охватить весь буфер, вы должны сначала отправиться в его начало. Все экземпляры вплоть до конца буфера будут заменены; чтобы ограничиться заменой в части буфера, сузьте его до этой части перед выполнением замены (смотрите раздел Сужение). В режиме Transient Mark, если область активна, замена ограничена этой областью (смотрите раздел Режим Transient Mark).
Когда вы выходите из replace-string, точка остается на месте
последней замены. Значение точки в момент, когда была запущена команда
replace-string, запоминается в списке пометок. C-u
C-SPC перемещает вас обратно.
Числовой аргумент ограничивает замену совпадениями, которые окружены ограничителями слов. Значение аргумента роли не играет.
Команда M-x replace-string заменяет точные совпадения с
одиночной строкой. Аналогичная команда replace-regexp замещает
любое совпадение с заданным образцом.
В replace-regexp, новая-строка не обязательно должна быть
константой: она может ссылаться на все или часть того, что соответствует
регулярному выражению regexp. `\&' в новой-строке
означает полный замещаемый текст. `\n', где n -- это
цифра, означает то, что было поставлено в соответствие n-ной
заключенной в скобки группе в регулярном выражении regexp. Чтобы
включить в новый текст знак `\', вы должны ввести `\\'.
Например,
M-x replace-regexp RET c[ad]+r RET \&-safe RET
заменит (например) `cadr' на `cadr-safe' и `cddr' на `cddr-safe'.
M-x replace-regexp RET \(c[ad]+r\)-safe RET \1 RET
делает обратное преобразование.
Если первый аргумент в команде замены набран в нижнем регистре, во
время поиска вхождений для замены регистр игнорируется -- при условии,
что case-fold-search не равна nil. Если
case-fold-search установлена в значение nil, регистр
учитывается во всех типах поиска.
Кроме того, когда аргумент новая-строка весь или частично написан строчными буквами, команды замены пытаются сохранить образец использования регистра в каждом вхождении. Таким образом, команда
M-x replace-string RET foo RET bar RET
заменяет `foo' в нижнем регистре на `bar' в нижнем регистре,
`FOO' в верхнем регистре на `BAR', а `Foo' с первой
заглавной буквой на `Bar'. (Три эти альтернативы: все строчные
буквы, все заглавные и первая заглавная -- единственные варианты,
которые может распознать replace-string.)
всегда
вставляется в том виде, в котором он дан, без изменения регистра.
Аналогично, если переменная case-replace или
case-fold-search установлена равной nil, замещение
происходит без изменения регистра.
Если вы хотите заменить только некоторые экземпляры `foo' на
`bar', но не все, вы не можете использовать обыкновенную
replace-string. Вместо этого используется M-%
(query-replace). Эта команда находит экземпляры `foo' один
за другим, отображает каждый экземпляр и спрашивает вас, надо ли его
заменять. Числовой аргумент говорит query-replace, что нужно
рассматривать лишь те экземпляры, которые окружены знаками-разделителями
слов. Эта команда сохраняет регистр так же, как и
replace-string, при условии, что case-replace не равна
nil, как это обычно и бывает.
За исключением запроса подтверждения, query-replace работает
точно так же, как replace-string, а query-replace-regexp
--- как replace-regexp. Эта команда запускается при помощи
C-M-%.
Когда вам показывают вхождение строки или совпадение с регулярным выражением regexp, вы можете набрать следующее:
query-replace, так что
если вы хотите делать дальнейшие замены, вы должны использовать C-x
ESC ESC RET, чтобы запустить замену заново
(смотрите раздел Повтор команд минибуфера).
query-replace хранится только
одна предыдущая позиция замены.
Некоторые другие знаки являются синонимами перечисленных выше: y, n и q эквивалентны SPC, DEL и RET.
Кроме этих знаков, любой другой выходит из query-replace и
снова считывается как часть последовательности ключей. Таким образом,
если вы напечатаете C-k, она выйдет из query-replace и
уничтожит текст до конца строки.
Чтобы перезапустить query-replace, когда вы уже из нее вышли,
используйте C-x ESC ESC, которая повторит
query-replace, так как она использовала минибуфер для чтения
аргументов. Смотрите раздел Повторение команды.
Смотрите также раздел Преобразование имен файлов в Dired, чтобы узнать о командах Dired для переименования, копирования или создания ссылок на файлы путем замены в их именах совпадений с регулярным выражением.
образец не содержит заглавных букв, а case-fold-search отлична от
nil.
Кроме того, вы можете использовать из Emacs программу grep
для поиска совпадений с регулярным выражением в группе файлов, а затем
обратиться к найденным совпадениям последовательно или в произвольном
порядке. Смотрите раздел Поиск с Grep под Emacs.
| Главная |