Пошук і заміна – ЧАСТИНА 3

‘% Або точці

Зауважимо, що спеціальні знаки регулярних виразів всередині такої безлічі більше не є спеціальними Усередині знакового безлічі існують зовсім інший набір спеціальних знаків: ], – і ‘^’

Щоб включити в знаковий набір ], ви повинні поставити його першим Наприклад, [] а] відповідає ] або а. Щоб включити -, напишіть – першим або останнім знаком в наборі або помістіть його після вказівки інтервалу Таким чином, [] -] відповідає ] і -.

Щоб включити в набір знак ^, пишіть його де завгодно, але не першим

Якщо ви задаєте інтервал при пошуку без урахування регістру, ви повинні або написати обидва кінці інтервалу великими літерами, або обидва малими, або обидва вони не повинні бути буквами Поведінка інтервалу з кінцями, заданими в різних регістрах, визначено погано і може бути змінено в майбутніх версіях Emacs

[^ ..] [^ Починає додатковий набір знаків, який відповідає будь-якому знаку, виключаючи описані в ньому Таким чином, [^ a-z0-9A-Z] відповідає всім знакам, виключаючи букви і цифри

‘^ Не є спеціальним в наборі знаків, якщо він не стоїть першим Знак,

наступний за ^, трактується так, як якби він був першим (іншими словами,

‘- І ] тут не є спеціальними)

Додатковий набір знаків може відповідати знаку нового рядка, якщо він не згадується як один з незбіжних знаків Це суперечить способом обробки регулярних виразів в таких програмах, як grep

^ Це спеціальний знак, який відповідає порожній рядку, але тільки на початку рядка зіставляється тексту В іншому випадку, порівняння не вдасться Таким чином, ^ foo відповідає Foo, яка зустрінута на початку рядка

$ Подібний ^, але порівняння відбувається тільки в кінці рядка Таким чином,

‘Xx * $ відповідає рядку з одного або більше x в кінці рядка

\ Має дві функції: скасовує особливий сенс спеціальних знаків (включаючи \)

і вводить додаткові спеціальні конструкції

Так як \ скасовує особливий сенс спеціальних знаків, то \ $ – це регулярний вираз, яке відповідає тільки $, а \ [ – регулярний вираз, яке відповідає тільки [, і так далі

Зауваження: для історичної сумісності спеціальні знаки трактуються як звичайні знаки, якщо вони знаходяться в контексті, в якому їх спеціальний зміст не має значення Наприклад, * foo трактує * як звичайний, так як не існує попереднього виразу, на яке може подіяти *. Погано бути залежним від цього правила краще завжди явно скасовувати особливий сенс спеціальних знаків незалежно того, де вони знаходяться

У більшості випадків \, за яким слідує будь-який знак, відповідає тільки цьому знаку Однак, існує кілька винятків: двухзнаковие послідовності, що починаються з \, мають особливий сенс Другий знак в такій послідовності завжди звичайний, коли зустрічається сам по собі Тут представлена ​​таблиця конструкцій з \.

\ | Описує альтернативу Два регулярних вирази a і b з \ | між ними формують вираз, який відповідає будь-якому з них окремо: або a, Або b Це працює так: спочатку пробується a, І якщо відповідність не знайдено, пробується b

Таким чином, foo \ | bar відповідає або foo, або bar, але не інший рядку

‘\ | Застосовується до найбільшим охоплює виразами Тільки охоплює-

тивающие дужки \ (.. \) можуть обмежити групуються силу \ |.

Існує можливість повного зворотного відновлення для обробки багаторазових використань \ |.

\ (.. \) Групує конструкція, яка служить для трьох цілей:

1 Щоб відокремити набір альтернатив \ | від інших операцій Таким обра-

зом, \ (foo \ | mar \) x відповідає або foox, або marx.

2 Щоб обмежити складний вираз для дії Постфіксний операторів *, + і ?’. Таким чином, ba \ (na \) * відповідає bananana і так далі з будь-яким (нульовим або великим) числом рядків na.

3 Щоб відзначити відповідну підрядок для майбутньої посилання

Це останнє застосування не є наслідком ідеї обмеження групи це окрема властивість, яке визначено як друге значення тієї ж самої конструкції \ (.. \). На практиці між цими двома значеннями не чиниться протиріч

\n               відповідає тексту, що співпала з n-Ним появою конструкції \ (..

\)’

Після кінця конструкції \ (.. \) зіставлення запамятовує початок і кінець тексту, що співпала з цією конструкцією Потім, пізніше в регулярному виразі, ви можете використовувати \, за яким слідує цифра n, Щоб сказати: зіставити з тому ж текстом, який збігся з n-Ним появою конструкції \ (.. \) .

Рядках, що відповідають першим девяти конструкціями \ (.. \), які зявлятимуться в регулярному виразі, присвоюються номери від 1 до 9 в тому порядку, в якому в регулярному виразі зявилися відкривають дужки Конструкції від \ 1 до \ 9 можуть використовуватися для посилання на текст конструкції \ (.. \) з цим номером

Наприклад, \ ( * \) \ 1 відповідає будь-якому рядку, що не містить знаків перекладу рядка, яка складається з двох однакових половин \ ( * \) Відповідає першій половині, яка може бути будь-який, але \ 1, що йде слідом, повинна відповідати точно такому ж тексту

Якщо для якої-небудь конструкції \ (.. \) знайдено більше одного відповідності (що може легко статися, якщо за нею слід *), то запамятовується тільки останній збіг

\ Відповідає порожній рядку, але тільки на початку буфера або рядки, де про-

виходить пошук

\ Відповідає порожній рядку, але тільки в кінці буфера або рядки, де від-

ходить пошук

\ = Відповідає порожній рядку, але тільки в точці

\ B відповідає порожній рядку, якщо ця конструкція знаходиться на початку або кінці слова Таким чином, \ bfoo \ b відповідає будь-якому появі foo як окремого слова Bballs \ B відповідає ball або balls як окремим словам

‘\ B знаходить відповідність на початку або кінці буфера, незалежно від того, який текст йде далі

\ B відповідає порожній рядку, якщо тільки вона знаходиться не на початку або кінці слова

\ < відповідає порожній рядку, якщо вона знаходиться на початку слова. '\ <' Знаходить відповідність на початку буфера, але тільки якщо потім йде знак, що є частиною слова.

\> відповідає порожній рядку, якщо вона знаходиться в кінці слова \> Знаходить відповідність наприкінці буфера, але тільки якщо буфер завершується знаком, що є частиною слова

\ W відповідає будь-якому знаку, що є частиною слова Які саме це знаки, визначає синтаксична таблиця Див Розділ 316 [Синтаксис], с 366

\ W відповідає будь-якому знаку, який не є частиною слова

\sc              відповідає будь-якому знаку, чий синтаксис визначається кодом c Тут c

– Це знак, який являє собою синтаксичний код, наприклад, це

‘W для частини слова, – для пробільних знаків, ( для відкриває дужки, і так далі Ви можете позначити пробільний знак (який може бути перекладом рядка) або як -, або одним пропуском

\Sc             відповідає будь-якому знаку, чий синтаксис не визначається кодом c

Конструкції, які мають відношення до слів і синтаксису, управляються установками в синтаксичної таблиці (див Розділ 316 [Синтаксис], с 366)

Далі представлено складне регулярне вираз, що використовується Emacs для розпізнавання кінця пропозиції разом з будь-якими пробільними знаками, які йдуть слідом Воно дано в синтаксисі Лиспа, щоб дати вам можливість відрізнити прогалини від знаків табуляції У синтаксисі Лиспа, константная рядок починається і закінчується подвійними лапками \ ‘ Позначає подвійні лапки як частина регулярного виразу, ‘\\’

позначає зворотну косу риску, \ t позначає знак табуляції, а \ n – знак нового рядка

&quot[?!][]\&quot’)]*\\($\\|\t\\|  \\)[ \t\n]*&quot

Тут послідовно містяться чотири частини: набір знаків, відповідний точці,

‘?’ Або !’; набір знаків, відповідний парним квадратним дужки, лапки або круглі дужки, повторюваним будь-яке число разів альтернатива, укладена в дужки із зворотними косими рисами, яка відповідає кінця рядка, табуляції або двом пробілам і набір знаків, відповідний будь-яким пробільним знакам, повторюваним будь-яке число разів

Щоб ввести це регулярний вираз інтерактивно, ви надрукували б hTABi, Щоб отримати знак табуляції, і Cj, щоб отримати знак перекладу рядка Ви також друкували б поодинокі зворотні косі риси як є, а не дублювали б їх відповідно до синтаксисом Лиспа

126  Пошук і регістр букв

Всі види наращиваемого пошуку в Emacs зазвичай ігнорують регістр тексту, в якому відбувається пошук, якщо ви задали текст в нижньому регістрі Таким чином, якщо ви запросили пошук foo, то збігами вважаються і Foo, і foo. Регулярні вирази, і зокрема набори знаків, також включаються до це правило: [aB] відповідало б

‘A, або A, або b або B.

Головна буква в будь-якому місці рядка наращиваемого пошуку робить цей пошук від регістру Таким чином, пошук Foo не знайде foo або FOO. Це застосовується також і до пошуку регулярного виразу Цей ефект зникає, якщо ви видалили заголовні букви з рядка пошуку

Якщо ви встановите змінну case-fold-search рівний nil, всі букви повинні будуть збігатися точно, включаючи регістр Ця змінна своя для кожного буфера її зміна зачіпає тільки поточний буфер, але існує значення за замовчуванням, яке ви теж можете змінити Див Розділ 3124 [Локальні змінні], с 350 Ця змінна застосовується також і до ненаращіваемому пошуку, включаючи ті його різновиди, які здійснюються командами заміни (див Розділ 127 [Заміна], с 95) і командами пошуку в історії мінібуфера (див Розділ 54 [Історія мінібуфера], с 49)

127  Команди заміни

Глобальні команди пошуку і заміни не потрібні в Emacs так часто, як в інших редакторах1, але вони доступні Крім простої команди Mx replace-string, яка аналогічна такий же команді в більшості редакторів, існує команда Mx query-replace, яка для кожної появи зразка запитує вас, чи треба його замінювати

Команди заміни зазвичай працюють з текстом від точки до кінця буфера проте, в режимі Transient Mark вони діють на область, коли мітка активна Всі команди заміни замінюють один рядок (або регулярне вираз) одним рядком заміни Можна виконати паралельно кілька замін, використовуючи команду expand-region-abbrevs (див Розділ 243 [Розшифровка скорочень], с 258)

1271  Безумовна заміна

M-x replace-string hRETрядок hRETноварядок hRETi

Замінює кожне входження рядка на новурядок

1 У деяких редакторах операції пошуку і заміни – це єдиний зручний спосіб зробити одна зміна в тексті

M-x replace-regexp hRETi regexp hRETноварядок hRETi

Замінює кожне збіг з regexp на новурядок

Щоб замінити кожен випадок входження foo після крапки на bar, використовується команда Mx replace-string з двома аргументами foo і bar. Заміщення відбувається тільки в тексті після крапки, так, якщо ви хочете охопити весь буфер, ви повинні спочатку відправитися в його початок Усі примірники аж до кінця буфера будуть замінені щоб обмежитися заміною у частині буфера, звузьте його до цієї частини перед виконанням заміни (див Розділ 308 [Звуження], с 335) У режимі Transient Mark, якщо область активна, заміна обмежена цією областю (див Розділ 82 [Transient Mark], с 64)

Коли ви виходите з replace-string, точка залишається на місці останньої заміни Значення точки в момент, коли була запущена команда replace-string, запамятовується в списку позначок C-u C-hSPCпереміщує вас назад

Числовий аргумент обмежує заміну збігами, які оточені обме-

телямі слів Значення аргументу ролі не грає

1272  Заміна регулярних виразів

Команда Mx replace-string замінює точні співпадіння з одиночною рядком Ана-

логічна команда replace-regexp заміщає будь-який збіг з заданим зразком

У replace-regexp, новарядок не обовязково повинна бути константою: вона може посилатися на всі або частину того, що відповідає регулярному виразу regexp \ & В новійрядку означає повний заміщається текст \n, Деn – Це цифра, означає те, що було поставлено у відповідність n-Ной укладеної в дужки групі в регулярному виразі regexp Щоб включити в новий текст знак \, ви повинні ввести \ \. Наприклад,

M-x replace-regexp hRETi  c[ad]+r hRETi  \&amp-safe hRETi

замінить (наприклад) cadr на cadr-safe і cddr на cddr-safe.

M-x replace-regexp hRETi  \(c[ad]+r\)-safe hRETi  \1  hRETi

робить зворотне перетворення

1273  Команди заміни і регістр букв

Якщо перший аргумент в команді заміни набраний у нижньому регістрі, під час пошуку входжень для заміни регістр ігнорується – за умови, що case-fold-search не дорівнює nil Якщо case-fold-search встановлена в значення nil, регістр враховується в усіх типах пошуку

Крім того, коли аргумент новарядок весь або частково написаний малими літерами, команди заміни намагаються зберегти зразок використання регістра в кожному входженні Таким чином, команда

M-x replace-string hRETi  foo  hRETi  bar  hRETi

замінює foo в нижньому регістрі на bar в нижньому регістрі, FOO в верхньому регістрі на BAR, а Foo з першої великою літерою на Bar. (Три ці альтернативи: усі малі літери, усі великі і перша заголовна – єдині варіанти, які може розпізнати replace-string)

Якщо в рядку підстановки використані літери верхнього регістру, то вони залишаються такими при кожній вставці цього тексту Якщо літери верхнього регістру використовуються в першому аргументі, то другий аргумент завжди вставляється в тому вигляді, в якому він даний, без зміни регістру Аналогічно, якщо змінна case-replace або case-foldsearch встановлена ​​рівної nil, заміщення відбувається без зміни регістру

1274  Заміна з підтвердженням

M-% рядок hRETноварядок hRETi

M-x query-replace hRETрядок hRETноварядок hRETi

Замінює деякі входження рядка на новурядок

C-M-% regexp  hRETноварядок hRETi

M-x query-replace-regexp hRETi regexp hRETноварядок hRETi

Замінює деякі збіги з regexp на новурядок

Якщо ви хочете замінити тільки деякі екземпляри foo на bar, але не всі, ви не можете використовувати звичайну replace-string Замість цього використовується M-% (query-replace) Ця команда знаходить екземпляри foo один за іншим, відображає кожен екземпляр і питає вас, чи треба його замінювати Числовий аргумент говорить query-replace, що потрібно розглядати лише ті екземпляри, які оточені знаками-роздільниками слів Ця команда зберігає регістр так само, як і replacestring, за умови, що case-replace не дорівнює nil, як це зазвичай і буває

За винятком запиту підтвердження, query-replace працює точно так само, як replace-string, а query-replace-regexp – як replace-regexp Ця команда запускається за допомогою CM-%

Коли вам показують входження рядка або збіг з регулярним виразом

regexp, Ви можете набрати наступне:

hSPCi              щоб замінити це входження на новурядок

hDELi              щоб перейти до наступного входженню, не замінюючи це

, (Кома)

щоб замінити це входження і показати результат Потім у вас запитують введення ще одного знака, щоб дізнатися, що робити далі Так як заміна вже зроблена, то hDELi  і hSPCi  в цій ситуації еквівалентні обидві переходять до наступного входження

Ви можете набрати в цьому місці Cr (дивіться нижче), щоб змінити замінений текст Ви можете також набрати Cx u, щоб скасувати зроблену заміну ця команда виходить з query-replace, так що якщо ви хочете робити подальші заміни, ви повинні використовувати Cx hESCi hESCi hRETi, Щоб запустити заміну заново (див Розділ 55 [Повтор], с 50)

hRETi             щоб вийти без здійснення подальших замін

. (Точка) щоб замінити цей екземпляр і потім вийти без продовження пошуку сліду-

чих входжень

! щоб замінити всі залишилися екземпляри без повторних запитів

^ Щоб повернутися до положення попереднього входження (або до того, що їм було), якщо ви змінили його помилково Це робиться за допомогою виштовхування зі списку позначок Можна використовувати тільки один ^ поспіль, так як під час роботи query-replace зберігається тільки одна попередня позиція заміни

Cr щоб увійти в новий рівень рекурсивного редагування, в тому випадку, коли екземпляр потребує скоріше в редагуванні, ніж просто в заміні його новоїрядком Коли ви зробите це, вийдіть з цього рівня рекурсивного редагування, набравши CMc, щоб перейти до наступного входженню Див Розділ 3012 [Рекурсивне редагування], с 338

Cw щоб видалити це входження і потім увійти в новий рівень рекурсивного редагування, як в Cr Використовуйте рекурсивне редагування для вставки тексту і заміни віддаленого входження рядка Коли ви закінчите, вийдіть з цього рівня рекурсивного редагування за допомогою CMc, щоб перейти до наступного входженню

Cl щоб відновити зображення екрана Потім ви повинні набрати ще один знак, щоб вказати, що робити з цим входженням

Ch щоб переглянути повідомлення, резюмуюче ці варіанти Потім ви поса-

ни набрати ще один знак, щоб вказати, що робити з цим входженням

Деякі інші знаки є синонімами перерахованих вище: y, n і q еквівалента

лентний hSPCi, hDELі hRETi

Крім цих знаків, будь-який інший виходить з query-replace і знову зчитується як частина послідовності ключів Таким чином, якщо ви надрукуєте Ck, вона вийде з query-replace і знищить текст до кінця рядка

Щоб перезапустити query-replace, коли ви вже з неї вийшли, використовуйте Cx hESCi hESCi, Яка повторить query-replace, так як вона використовувала мінібуфер для читання аргументів Див Розділ 411 [Повторення], с 43

Дивіться також Розділ 289 [Перетворення імен файлів], с 297, щоб дізнатися про команди Dired для перейменування, копіювання або створення посилань на файли шляхом заміни в їх іменах збігів з регулярним виразом

128  Інші команди пошуку в циклі

Тут представлені деякі інші команди, які знаходять збіги з регулярними виразами Всі вони діють від точки до кінця буфера, і всі вони ігнорують при зіставленні регістр, якщо зразок не містить заголовних букв, а case-fold-search відмінна від nil

M-x occur hRETi regexp hRETi

Виводить перелік, що показує кожен рядок буфера, яка містить збіг з regexp Числовий аргумент задає число рядків контексту, які повинні бути надруковані перед і після кожної порівнюєш рядка значень за замовчуванням – не друкувати контекст Щоб обмежити пошук частиною буфера, звузьте до цієї частини (див Розділ 308 [Звуження], с 335)

Буфер * Occur *, в який записується висновок, служить як меню для пошуку входжень в їх оригінальному контексті Клацніть Mouse-2 на входженні, перерахованому в * Occur *, або помістіть там точку і натисніть hRETi це перемкне в буфер, де робився пошук, і перемістить точку до оригіналу обраного входження

M-x list-matching-lines

Синонім для M-x occur

M-x count-matches hRETi regexp hRETi

Друкує число збігів з regexp після точки

M-x flush-lines hRETi regexp hRETi

Видаляє кожен рядок, наступну після крапки і містить збіг з

regexp

M-x keep-lines hRETi regexp hRETi

Видаляє кожен рядок, наступну після точки і не містить збіг з regexp

Крім того, ви можете використовувати з Emacs програму grep для пошуку збігів з регулярним виразом в групі файлів, а потім звернутися до знайдених збігам послідовно або в довільному порядку Див Розділ 232 [Пошук з grep], с 248

Джерело: Річард Столмен, Керівництво по GNU Emacs

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*