Why matchstr returns also text matched by zero-width pattern?

38 views
Skip to first unread message

Martin Jiricka

unread,
Sep 15, 2012, 4:10:49 PM9/15/12
to v...@vim.org
Dear vim users,

I do not understand why output of this command: `echo
matchstr('123abc','\v(123)\@=abc')` is `123abc`. I'm using zero-width
pattern, so I would like to get just `abc`. What am i doing wrong?

Thank you very much!

Martin Jiricka

Ben Fritz

unread,
Sep 17, 2012, 11:19:31 AM9/17/12
to vim...@googlegroups.com, v...@vim.org
On Saturday, September 15, 2012 3:10:49 PM UTC-5, Martin Jiricka wrote:
> Dear vim users,
>
>
>
> I do not understand why output of this command: `echo
>
> matchstr('123abc','\v(123)\@=abc')` is `123abc`. I'm using zero-width
>
> pattern, so I would like to get just `abc`. What am i doing wrong?
>
>

Since you're using "very magic", \@= isn't a zero-width match for the preceding atom. It's an optional match for a literal '@' character. :help /\=.

Additionally, if this WERE working as you expect, your pattern would NEVER match. You are saying,

"match abc where 123 also matches in the same position"

which cannot possibly succeed, because 123 does not match where abc matches.

I think you wanted one of these:

\v(123)@<=abc
\(123\)\@<=abc

Martin Jiricka

unread,
Sep 17, 2012, 1:07:58 PM9/17/12
to vim...@googlegroups.com, v...@vim.org
Hello!

First of all, thank you for your reply!

> I think you wanted one of these:
> \v(123)@<=abc

Yes, this is what I wanted.

> Additionally, if this WERE working as you expect, your pattern would NEVER
> match. You are saying,
> "match abc where 123 also matches in the same position"
> which cannot possibly succeed, because 123 does not match where abc matches.

I don't get this. Of course I didn't want to match 'abc' on '123'. (That's the purpose of regexes, match pattern where the pattern match, I would say...?) I posted simplified example, originally I wanted to match last word before the parenthesis, which is a function name. The '@<=' works fine for this.

Thank you for your help!

Martin Jiricka


Ben Fritz

unread,
Sep 18, 2012, 11:02:31 AM9/18/12
to vim...@googlegroups.com, v...@vim.org
Yes, and @<= is what you wanted. You used @=, which is a zero-width look-ahead, not a look-behind.

E.g. /\(abc\)\@=\a\+ will match the whole string "abcdefghij"; it says "find a string of alphabetic characters starting with 'abc'". /\(abc\)\@<=\a\+ will match the "defghij" in "abcdefghij" only; it says, "find a string of alphabetic characters preceded by 'abc'".

Ben Fritz

unread,
Sep 18, 2012, 11:03:23 AM9/18/12
to vim...@googlegroups.com, v...@vim.org
Incidentally, I cannot recall ever having a use for \@=. As the help says, it does the same thing as \&.

Martin Jiricka

unread,
Sep 18, 2012, 7:35:33 PM9/18/12
to vim...@googlegroups.com, v...@vim.org

>
> > Yes, and @<= is what you wanted. You used @=, which is a zero-width look-ahead, not a look-behind.
>

Now I understand what you meant with "123 does not match where abc matches"! I misunderstood the whole look ahead concept. I find very useful this explanation:

http://stackoverflow.com/questions/2973436/regex-lookahead-lookbehind-and-atomic-groups


>
> Incidentally, I cannot recall ever having a use for \@=. As the help says, it does the same thing as \&.

I think lookaheads are good for defining more conditions which would be difficult to define in one expression. Like "four-letter world containing a vowel". Without lookaheads I think this could be done only with regex defined with four branches (each fixing a vowel on certain position).

Thank you for your patience :)

All the best

Martin



Reply all
Reply to author
Forward
0 new messages