Practical Vim< /a> vit Practical Vim< /a> Note that the styling for a Visual selection is the... development I thought I knew Vim, but Practical" name="description"/>
Tải bản đầy đủ - 0 (trang)
Tip 77. Stake the Boundaries of a Match

Tip 77. Stake the Boundaries of a Match

Tải bản đầy đủ - 0trang

Escape Problem Characters

• 193

Lookaround Expressions

Vim’s \zs and \ze items are conceptually similar to Perl’s lookaround assertions.a

Although the syntax differs between the regex engines in Perl and Vim, the \zs item

is roughly equivalent to positive lookbehind, while \ze is equivalent to positive lookahead.

As you might expect, Perl also supports negative variants of the lookaround assertions.

These are zero-width items that match only if the specified pattern is not present.

Vim also supports the full matrix of negative/positive lookahead/lookbehind assertions, but again, the syntax differs from Perl. For a side-by-side comparison, look up

:h perl-patterns .

Instead of using \zs and \ze, we could rewrite the /\v"\zs[^"]+\ze" pattern from Tip

77, on page 192, using Vim’s positive lookaround items, like so:


I don’t know about you, but I find the version using \zs and \ze easier to parse. Negative

lookaround expressions are used heavily in some of Vim’s syntax highlighting definitions, but I’ve found little need for them in everyday usage. However, I’ve found many

uses for positive lookaround expressions, so it seems fitting that they should have

their own shorthand tokens, namely \zs and \ze.


that are anything but a quote mark. In the final rendition of the pattern, we

add the \zs item after the opening quote mark and the \ze item before the

closing quote mark. This excludes the quote marks from the match, leaving

only the contents of the quotes highlighted. Note that the quote marks are

still a critical element in the pattern, even though they are excluded from the


Tip 78

Escape Problem Characters

The \V literal switch makes it easier to search for text verbatim because it disables the special meanings for the ., +, and * symbols, but there are a few

characters whose special meaning can’t be turned off. In this advanced tip,

we’ll look at how to handle these.

report erratum • discuss

Chapter 12. Matching Patterns and Literals

• 194

Escape / Characters When Searching Forward

Take this excerpt from a Markdown document (the true URL is at vimdoc.,2 but it has been abbreviated here to fit):


Search items: [\\][s]



Suppose that we want to search for all instances of the URL\\. Rather than typing it out in full, we’ll just yank it into a

register so that we can paste it into our search field. We want to match this

text exactly as is, so we’ll use the \V literal switch.

With our cursor placed anywhere inside the brackets, we can yank the URL

into register u with the command "uyi[ (mnemonic: u stands for URL). We

then type /\Vu to populate the search field with the contents of that

same register. Our search prompt looks like this:


When we execute the search, we get this result:

Search items: [\\][s]



What’s going on here? When we pasted the full URL into the search field, Vim

interpreted the first / character as a search field terminator (see Search Field

Terminators, on page 197). Everything after that first forward slash was ignored,

so our search string became merely http:.

When searching forward, we have to escape / characters. This is required

whether we are doing a very magic search (with the \v pattern switch) or a very

nomagic search (with the \V literal switch). Let’s amend the previous search,

prefixing each / character with a backslash:


This time, the result is closer to what we would expect:

Search items: [\\][s]




report erratum • discuss

Escape Problem Characters

• 195

It’s still not perfect. The match stops short of the final backslash. We’ll find

out why soon, but first, let’s consider searching backward.

Escape ? Characters When Searching Backward

When searching backward, the ? symbol acts as the search field terminator.

That means we don’t have to escape / characters, but instead we have to

escape the ? symbol. Watch what happens if we search backward for the URL

that we yanked into register u:


Without escaping anything, Vim matches the string “


Search items: [\\][s]



That’s a better result than when we searched forward without escaping anything, but it still doesn’t match the full URL. We can do better if we prepend

the ? character with a backslash:


That matches the following:

Search items: [\\][s]



Escape \ Characters Every Time

There’s one more character that we have to escape in the search field: the

backslash. Normally, a \ indicates that the next character is to be given some

special treatment. If we double it up as \\, the first backslash cancels out the

special meaning of the second one. In effect, we’re telling Vim to search for a

single backslash character.

In our example text, we’re searching for a URL that includes two consecutive

backslashes. We have to include two backslashes in the search field for each

of them. Searching forward, we end up with this:


At last! Our search query matches the entire URL:

Search items: [\\][s]



report erratum • discuss

Chapter 12. Matching Patterns and Literals

• 196

The backslash character always needs to be escaped, whether we’re searching

forward or backward.

Escape Characters Programmatically

Escaping characters by hand is laborious, error-prone work. Fortunately,

Vim script includes a library function that can do the hard work for us:

escape({string}, {chars}) (see :h escape() ).

The {chars} argument specifies which characters must be escaped with a

backslash. If we’re searching forward, we could call escape(@u, '/\'), which would

prefix each / and \ character with a backslash. If we were searching backward,

we could instead call escape(@u, '?\').

First, make sure that the URL we want to search for is still stored in the u

register. Then we’ll bring up the search prompt by pressing / or ?; either one

will work just fine. Enter the \V literal switch and then type = . That

switches from the search prompt to the expression register prompt. Now we

type this:

=escape(@u, getcmdtype().'\')

When we press , the escape() function is evaluated, and the returned value

gets inserted into the search field. The getcmdtype() function simply returns a

/ symbol if we’re searching forward or a ? symbol if we’re searching backward

(see :h getcmdtype() ). In Vim script, the . operator performs string concatenation, so getcmdtype().'\' produces “/\” if we’re searching forward and ?\ if we’re

searching backward. The end result is that no matter which way we’re

searching, this expression escapes the contents of the u register so that we

can find it.

Switching to the expression register and calling the escape() function by hand

still involves a lot of typing. With just a little bit more Vim script, we could

automate this, making it more convenient to use. Skip ahead to Tip 86, on

page 212, for an example.

report erratum • discuss

Escape Problem Characters

• 197

Search Field Terminators

You might be wondering why the search field has to treat any character as a terminator. Why not just accept that everything following the search prompt is to be included

in the search match? The behavior of Vim’s search command can be tuned by

appending certain flags after the search field terminator. For example, if we run the

command /vim/e , then our cursor will be placed at the end of any matches rather

than at the start. In Tip 83, on page 204, we’ll learn how to exploit this feature rather

than let it exploit us.

There is one way of entering a pattern without having to worry about search field

terminators, but it works only in GVim: use the :promptfind command (see :h :promptfind ).

This brings up a graphical dialog window with a field labeled “Find.” You can enter

the / and ? characters here without having to escape them. However, the \ and newline

characters still cause problems.

report erratum • discuss



Having studied Vim’s regular expression engines in the previous chapter, let’s

see how we can put them to use with the search command. We’ll start with

the basics: how to execute a search, highlight matches, and jump between

them. Then we’ll learn a couple of tricks that exploit Vim’s incremental search

feature, which not only gives us instant feedback but can also save us typing

by autocompleting our match. We’ll also learn how to count the number of

matches that occur in a document.

The search offsets feature allows us to position our cursor relative to a match.

We’ll look at one scenario where search offsets can streamline our workflow.

Then we’ll see how search offsets can be exploited to operate on a complete

search match.

Composing a regular expression—and getting it right—often takes a few

attempts, so developing a workflow that allows us to iterate on a pattern is

important. We’ll learn about two methods for doing this: calling up our search

history and working in the command-line window.

Have you ever wished for a simple way of searching for text that’s already

present in your document? We’ll finish by devising a simple customization

that overrides the * command to search for the current visual selection.

Tip 79

Meet the Search Command

In this tip, we’ll cover the basics of using the search command, including how

to specify the direction of a search, repeat (or reverse) the last search, and work

with the search history.

report erratum • discuss

Chapter 13. Search

• 200

Execute a Search

From Normal mode, the / key brings up Vim’s search prompt. Here we can

enter the pattern, or literal text, that we want to search for. Vim does nothing

until we press the key to execute the search. If we press the key

instead, the search prompt will be dismissed and we’ll return to Normal mode.

When we execute a search, Vim scans forward from the current cursor position, stopping on the first match that it finds. If nothing is found before the

end of the document, Vim informs us “search hit BOTTOM, continuing at

TOP.” This means that in some circumstances, a forward search can take us

backward. That’s not as disorienting as it might sound. Just remember that

the search command wraps around the document, and it’ll make sense.

If you ever need to search from the current cursor position to the end of the

document without wrapping around, you can disable the ‘wrapscan’ option (see

:h 'wrapscan' ).

Specify the Search Direction

When a search is initiated with the / key, Vim scans the document forward.

If we use the ? key to bring up the search prompt, Vim searches backward

instead. The search prompt always begins with either the / or ? character,

which indicates in what direction the search will scan.

Repeat the Last Search

The n command jumps to the next match, and the N command jumps to the

previous match. We can easily navigate between matches in the current

document with the n and N commands. But the definition of “next match”

depends on context.

The n command preserves the direction as well as any offsets that were applied

to the previous search (we’ll meet offsets in Tip 83, on page 204). So if we execute a forward search using / , then n will continue searching forward.

Whereas if we used ? for the original search, then n will continue backward.

Meanwhile, the N command always goes in the opposite direction from the

last search.

Sometimes we might want to repeat a search using the same pattern but

changing the direction or offset. In this case, it’s useful to know that if we

execute a search without providing a pattern, Vim will just reuse the pattern

from the previous search. Table 22, Options for Repeating a Search, on page

201 summarizes the matrix of options for repeating a search:

report erratum • discuss

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tip 77. Stake the Boundaries of a Match

Tải bản đầy đủ ngay(0 tr)