Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vim pattern matching two tokens without another given token inbetween

Using vim 7.2, for this text:

foo foo token foo foo countertoken foo foo token foo target foo foo countertoken foo

I want to match each string starting with 'token' and ending with 'target', that doesn't contain 'countertoken'.

So, in the above example, I want to match this:

foo foo token foo foo countertoken foo foo token foo target foo foo countertoken foo

but not this:

foo foo token foo foo countertoken foo foo token foo target foo foo countertoken foo

(The reason for this is that, in practice, I'm searching long files and I'm interested in the last 'token' before the 'target'. The tokens are a bit like XML tags, but it's not XML, so XML tools are no help. I know I could use \zs so the cursor lands on 'target' and then search backwards for 'token', but surely there's a one-step solution!)

I was hoping something like this would work, but it doesn't:

/token\(.*countertoken.*\)\@!*target

There are many such occurrences I'm interested in, and of course, the files I'm searching aren't really full of anything as regular as 'foo'.

Is there a one-line regex for this in vim?

like image 848
Michael Scheper Avatar asked Dec 14 '12 02:12

Michael Scheper


1 Answers

If you are only interested in the last token, you don't have to care about the countertoken. One possibility is to look for the last occurence of token and match everything until the next target.

/.*\zs\(token\).\{-}\(target\)

Explanation:

  • .*\zs - match last occurence.
  • \(token\) - match string "token"
  • .\{-} match non-greedy
  • \(target\) - match string "target"
like image 194
jens-na Avatar answered Nov 15 '22 04:11

jens-na