vim pattern matching two tokens without another given token inbetween
Asked Answered
C

1

8

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?

Combustible answered 14/12, 2012 at 2:10 Comment(0)
R
1

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"
Requirement answered 14/12, 2012 at 9:36 Comment(1)
Thanks, but that doesn't take into account that the last occurrence may include 'countertoken'. I realise I should clarify: the strings I'm interested in occur multiple times in the file, and any of them may or may not include the countertoken—I'm interested in when they don't. I've edited the question.Combustible

© 2022 - 2024 — McMap. All rights reserved.