29

"Zoom" anchors In addition to @jecxjo's answer, there are many situations where you can use the zero-width anchors \zs and \ze instead of positive lookaround. These anchors define the start (\zs) and the end (\ze) of the match within the full pattern. Examples foo\zsbar will match bar preceded by foo (foo not part of the match) foo\zebar will match foo ...


24

The obvious reason is that groups with two or more digits are ambiguous: should \12 be taken as group 12, or as group 1 followed by the string 2? There are other reasons related to efficiency (exponential matching time and the like). These were a show stopper when ed was written. Better algorithms have been discovered since then.


21

Vim's regex has special syntax for non-greedy versions of operators (it's kind of annoying, but you just have to memorize them): http://vimregex.com/#Non-Greedy The non-greedy version of * is \{-}. So, simply replace .* with .\{-}: :%s/\(https\?:\/\/.\{-}\/\).*/\1/gc


21

In summary, no. Vim's regex is a unique flavour, and there are no options to make it behave more like another flavour. I think this is a good thing. Magic The 'magic' option doesn't change the flavour of regex that Vim uses. It simply inverts the behaviour of many \-escaped atoms. For example, by default, + is a literal + character, where \+ means "one ...


19

Here you go: :g/foo/t.|s//bar Decomposing: :g/foo/ " start a global command applied on all lines matching 'foo' t. " duplicate the current line (the cursor is now on the new line) | " chain a new command s//bar " substitute the last searched element with 'bar' Because the g command will update the search pattern, so you can ...


19

Very simple approach: Move to the first line you want to delete. Record a macro: qa3ddjq Repeat it with a high number: 1000@a Step three will repeat the macro a thousand times or until an error is encountered. Hitting end of file (hence no lines to delete) produces an error and repetition of the macro is canceled. See :help recording.


18

Just to be clear… I believe you asked for this to be the result of the substitution? ############################################################################### # Trackpad, mouse, keyboard, Bluetooth accessories, and input # ############################################################################### running "Trackpad: enable tap to ...


18

You're almost there; you can also specify a range of lines, which is in the form of [line1],[line2][command], instead of just [line][command] (like you're using now). You can use . to refer to the current line. For the current & next line: :g/match/.,+1d For the current & previous line: :g/match/-1,.d For the previous, current, and next line: :g/...


17

Type in normal mode /<ctr-v>u0303 / - start search <Ctr-v>u - init utf-8 code input 0303 - hex code combine character. :he unicode Also :he mbyte-combining and :he utf-8-char-arg the last one covered case with commands like f, F and so on.


17

The easiest solution to me would be: :%norm j3dd That is: %: for every line norm: run the following keys as if in normal mode j3dd: go down on line then delete 3 lines So from the first line, go down to the second one and delete the next 3 lines. The second Text I want to keep. is now on the second line. Go down one line, delete 3. Rinse and repeat. ...


16

You can use the very-nomagic switch. See :h \V for details. This would give you %s/\V[ERROR] Login unsuccessful/something/g. There is also the nomagic switch \M, which is a lighter version of \V and does not seem to be widely used. Also note that you don't have to escape spaces as you do in your example, even when not using \V.


15

You could use the following solution: First use v$ to select the text from the cursor to the end of the line. Then use the following command: :s/\%V\ /_/g The \%V indicate to change the text in the previously visually selected area, see :h /\%V. If I take your example: function my_function(argument, another argument, but there are spaces) If my cursor ...


15

This looks like you indeed found an obscure bug. I have implemented the gn textobject back in 2012 for Vim 7.3 something. It basically works in the following way: 1) It searches backwards for the last match of the current regular expression. 2) It searches forward for the next match of the current regular expression. This should make clear, that the ...


15

With tpope/vim-surround, this is a simple cs)] away. cs is the "change-surrounding" operator ) is the "target" ] is the replacement


14

Do set foldmethod=expr and use 'foldexpr' to set a vim script expression that will define the fold start points. set foldmethod=expr set foldexpr=get(split(getline(v:lnum-1)),0,'')!=get(split(getline(v:lnum)),0,'')?'>1':'=' This looks more complicated than it is, because we can't easily use spaces in :set, but with spaces, and a newline or 2, it looks ...


14

Before googling, try the doc: From :h \% \%(\) A pattern enclosed by escaped parentheses. Just like \(\), but without counting it as a sub-expression. This allows using more groups and it's a little bit faster. {not in Vi} And :h \@<! \@<! Matches with zero width if the preceding atom does NOT match just before what follows. ...


13

It looks as if this is possible. There is a simple table to go from perl to vim. :h perl-patterns 9. Compare with Perl patterns *perl-patterns* Vim's regexes are most similar to Perl's, in terms of what you can do. The difference between them is mostly just notation; here's a summary of where they differ: Capability in ...


13

You can add custom syntax rules, and give them the @nospell keyword, this will tell Vim not to apply spell checking to this syntax match. For example: :syn match UrlNoSpell "\w\+:\/\/[^[:space:]]\+" contains=@NoSpell The above will work for text files, and some filetypes (such as markdown), but not for all filetypes. Note that I used a fairly simple regex ...


13

This solution doesn't show the difference between the two lines but highlight them and allow you to navigate through them with n and N like this: To do so add this function to your .vimrc: function! CompareLines(line1, line2) let l1 = getline(a:line1) let l2 = getline(a:line2) let pattern = "" for i in range(strlen(l1)) if strpart(...


12

How about this: /^[^#]*ipdb The first ^ will anchor the match to the start of the line, [^#] will match any character except a # (the ^ means to match any character except those given), and the * repeats this 0 or more times. See::help /^ :help /[ for some more information. Note that this will match all lines with ipdb which don't start with a comment, ...


12

With these settings: syn region FCall start='[[:alpha:]_]\i*\s*(' end=')' contains=FCall,FCallKeyword syn match FCallKeyword /\i*\ze\s*=[^=]/ contained hi FCallKeyword ctermfg=yellow I get: Here: I define a syntax region within which keyword arguments can be found, which would be the function call. The contains option lets me nest function calls. Within ...


11

You need to "build" your global command using :execute like so: for key in sort(keys(myDict)) execute '%g/^The ' . key . '/d' endfor See :h :exe for more help using :execute. Some thoughts: You may need to escaping your keys Might consider alternation. e.g. \(red\|blue\|green\) You may want to :delete into the black hole register to prevent any ...


11

I would use something like: :s/^#\s\+\(.\{-}\):/running "\1":/ ^# to match the # character anchored at the start of the line (this answers question 1) \s\+ to match any whitespace one or more times \( to start a group (this answers question 2) .\{-}\ to match any character 0 or more times in a non-greedy way; this is diffferent from .* in that it tries to ...


11

Vim's sort allows you to either skip {pattern}, or only consider it (with the r flag). A regular expression for the last comma-delimited column is easy to formulate: Skip everything until and including the last comma in a line: :sort/.*,/ For any other column, I would use the r flag, and skip N (here: 2) previous columns via \zs: :sort/\([^,]*,\)\{2}\zs[^,...


11

You don't need to match the start of the line. Instead, match any non-whitespace character. This should work: s/\S\zs\s\{2,}/ /g Explanation: \S\zs match any non-whitespace character and set start of pattern match after the character \s\{2,} match at two or more spaces


10

That's not a group, it's a range, and in Vim you can't use character classes (although it's possible in other regex implementations, e.g. in python). You'll have to use an alternation instead: /\(\w\|\s\) or: /\v(\s|\w) (or, the solution proposed by Peter Lewerin).


10

Unlike some implementations of regular expression engines, Vim's doesn't seem to support that notation ([\s\w]) in collections. One can use POSIX character class expressions, though. [:blank:] is the same as \s. [:space:] matches a greater number of whitespace characters than \s does, and seems to be equivalent to \_s. [:alnum:] approximates \w, but does ...


10

One way to do it would be this: :%s/\u\zsd\>/u/g Initially I assumed that the new Vim regex engine (being advertised as "faster, but limited") can't understand \u in :substitute, but this isn't the case. I rather think now that the OP forgot to use % and simply searched on the wrong line; this would explain the error message, but of course still needs ...


10

In that way, printf expects a decimal number to be converted to a hexadecimal one. All you need to do is convert the character to a number as follows: s/\([a-z]\)/\=printf("%#02x", char2nr(submatch(0)))/ See :help char2nr() for details.


10

Visually select all the lines you want to increment, and do the following: :s/\d\+/\=submatch(0) + 132 Does exactly what you describe. Visually selects a bunch of numbers, and adds a mathematical constant to each of them. If you leave of the /g flag, it will only increment the first number on each line. This uses the "expression register". To learn more, :...


Only top voted, non community-wiki answers of a minimum length are eligible