Вопрос или проблема
Когда я редактирую документ LaTeX в vim, часто мне нужно поискать фразу. Поскольку в LaTeX настроено обертывание строк, иногда половина фразы оказывается на одной строке, а другая половина — на следующей. В таком случае поиск не находит то, что я ищу. Например
blah blah blah hello
world blah blah blah
при поиске с помощью /hello world
я не нахожу то, что ищу. Есть ли быстрый и удобный способ изменить этот поиск, чтобы достичь нужного результата? Или лучше, способ сказать vim, чтобы он сопоставлял любые пробелы (пробел, табуляция, новая строка) с пробелом в строке поиска?
После дополнительных поисков, кажется, что наиболее простой способ сделать это – использовать \_s\+
. Например:
/hello\_s\+world
…где:
\s
без подчеркивания (если без нижнего подчеркивания) означает “символ пробела:<Space>
или<Tab>
”\_s
(с подчеркиванием) означает ”<Space>
или<Tab>
или конец строки”\_s\+
таким образом означает “один или более<Space>
или<Tab>
или символов конца строки”
Эта проблема была обсуждена на http://vim.wikia.com/wiki/Search_across_multiple_lines. Включена функция, которая может сделать то, что мне нужно.
function! SearchMultiLine(bang, ...)
if a:0 > 0
let sep = (a:bang) ? '\_W\+' : '\_s\+'
let @/ = join(a:000, sep)
endif
endfunction
command! -bang -nargs=* -complete=tag S call SearchMultiLine(<bang>0, <f-args>)|normal! /<C-R>/<CR>
Теперь вы можете выполнить многословный поиск, используя :S hello world
, и это преобразуется в hello\s\+world
и будет выполнен поиск. Еще одна приятная функция заключается в том, что это также добавит этот новый поиск в историю поиска. Это позволяет вам вернуться и изменить поиск, используя q/
, если это необходимо. Это также можно использовать для замены с помощью :%s//new thing/g
. Недостаток этого в том, что это не использует incsearch
, если он у вас включен.
Способ, который я знаю, не сложен, но немного утомителен. Замените каждый пробел в вашем поисковом запросе на следующее:
[ \t\n]\+
(Обратите внимание на пробел после [
.) Это синтаксис регулярного выражения. Если разобрать, это означает:
[...]
означает сопоставление с любым из списка символов внутри скобок.\t
— это табуляция\n
— это новая строка...\+
означает сопоставление с одним или более из вышеперечисленного.
Для получения дополнительной информации о регулярных выражениях вы можете спросить vim:
:help regexp
:help usr_27
Я лично предпочел бы использовать [ \t\n]*
вместо пробелов. Это будет сопоставлять ноль или более ‘ ‘, табуляции и новой строки. Таким образом, если один экземпляр вашего шаблона поиска охватывает разрыв строки, а другой — нет, оба будут сопоставлены.
Ответ или решение
Поиск в Vim с учетом переносов строк в LaTeX-документах
Редактирование документов в LaTeX с использованием Vim может вызывать определенные трудности, особенно когда речь идет о поиске фраз, разбросанных по линиям. Поскольку LaTeX часто использует автоматическую разбивку строк, фраза может разделяться переносами строк, что приводит к проблемам с поиском. Например, строка текста может выглядеть следующим образом:
blah blah blah hello
world blah blah blah
В данном случае команда поиска /hello world
не даст результатов, поскольку слова «hello» и «world» находятся на разных строках. К счастью, существует несколько методов для решения этой проблемы.
1. Использование регулярных выражений
Для того чтобы успешно осуществить поиск, можно использовать специальные символы, создающие паттерны, учитывающие переносы строк. Наиболее простой и популярный способ — это применить комбинацию \_s\+
, которая позволяет обрабатывать пробелы, табуляции и переносы строк. Пример команды поиска:
/hello\_s\+world
Объяснение команды:
\s
— обозначает символ пробела или табуляции.\_s
— учитывает не только пробелы и табуляции, но и переносы строк.\_s\+
— означает «один или несколько пробелов, табуляций или переносов строк».
Таким образом, вышеуказанная команда поможет найти желаемую фразу, даже если она разбросана по строкам.
2. Команда для многоточечного поиска
Если вам нужно чаще проверять фразы, которые могут располагаться на разных строках, можно реализовать пользовательскую команду в Vim. Например, следующая функция позволяет проводить многоточечный поиск:
function! SearchMultiLine(bang, ...)
if a:0 > 0
let sep = (a:bang) ? '\_W\+' : '\_s\+'
let @/ = join(a:000, sep)
endif
endfunction
command! -bang -nargs=* -complete=tag S call SearchMultiLine(<bang>0, <f-args>)|normal! /<C-R>/<CR>
С помощью этой команды вы можете использовать:
:S hello world
Эта команда автоматически преобразует ваш запрос в команду поиска, соответствующую вашему тексту, учитывая все типы пробелов.
3. Альтернативный способ с использованием регулярных выражений
Другим подходом является манипуляция с регулярными выражениями, заменяя каждый пробел в строке на следующий шаблон:
[ \t\n]\+
Такое регулярное выражение обозначает:
[...]
— соответствует любому символу из списка.\t
— символ табуляции.\n
— символ новой строки.\+
— соответствует одному или более из предыдущих символов.
Если вы хотите, чтобы поиск также работал с учетом ситуаций, когда шаблон может быть разбросан, используйте:
[ \t\n]*
Это регулярное выражение будет соответствовать нулю или более пробелам, табуляциям или переносам строк, что делает его более универсальным.
Заключение
Поиск фраз в Vim, учитывая переносы строк в LaTeX-документах, может быть выполнен несколькими способами: использование \_s\+
, написание пользовательской команды или применение регулярных выражений для более гибкого подхода. В зависимости от ваших потребностей, вы сможете выбрать наиболее подходящий метод для быстрого и эффективного поиска, избегая потери времени на ручное редактирование текста.