Quantcast

Matches with zero width if the preceding atom does NOT match at the current position.

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Matches with zero width if the preceding atom does NOT match at the current position.

baumann Pan
Hi Gurus,

I could not understand the descriptions below about the usage of \@!.
 "a.\{-}p\@!" will match any
        "a", "ap", "aap", etc. that isn't followed by a "p", because the "."
        can match a "p" and "p\@!" doesn't match after that.

I know why "a"  matches the pattern. but I don't understand why "ap"
could match the pattern "a.\{-}p\@!", so does "aap".
why "appppp" also matches the pattern?

from the pattern "a.\{-}p\@!", I can tell:
if the pattern is a.{-}p, it  will match ap, aaaap and
absdfasdfasdasdfasdp since .\{-} could be 0 to more chars as few as
possible,but followed with a p.
if\@! is after p, does it mean p should not appear at the end? why ap
is ok? adsfasdasdfap appp is matched the pattern  "a.\{-}p\@!"?????


TIA

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Matches with zero width if the preceding atom does NOT match at the current position.

Ben Fritz


On Aug 18, 11:02 am, baumann Pan <[hidden email]> wrote:

> Hi Gurus,
>
> I could not understand the descriptions below about the usage of \@!.
>  "a.\{-}p\@!" will match any
>         "a", "ap", "aap", etc. that isn't followed by a "p", because the "."
>         can match a "p" and "p\@!" doesn't match after that.
>
> I know why "a"  matches the pattern. but I don't understand why "ap"
> could match the pattern "a.\{-}p\@!", so does "aap".
> why "appppp" also matches the pattern?
>
> from the pattern "a.\{-}p\@!", I can tell:
> if the pattern is a.{-}p, it  will match ap, aaaap and
> absdfasdfasdasdfasdp since .\{-} could be 0 to more chars as few as
> possible,but followed with a p.
> if\@! is after p, does it mean p should not appear at the end? why ap
> is ok? adsfasdasdfap appp is matched the pattern  "a.\{-}p\@!"?????
>

'a' matches because .\{-} could be zero characters
'ap' matches because .\{-} matches the p, and then the next character
is not a p, matching the p\@! with zero width. End-of-line is also
"not a p" so that matches as well.

The root of the problem is the use of the '.' character which also
matches the p. If you want to rule out ap, aaap, etc. then you'd want
a[^p]* or similar.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Matches with zero width if the preceding atom does NOT match at the current position.

Ben Schmidt
In reply to this post by baumann Pan
Hi,

One mailing list is probably enough to post your questions to! :-) I'm
only replying on vim_use.

On 19/08/11 2:02 AM, baumann Pan wrote:

> Hi Gurus,
>
> I could not understand the descriptions below about the usage of \@!.
>   "a.\{-}p\@!" will match any
> "a", "ap", "aap", etc. that isn't followed by a "p", because the "."
> can match a "p" and "p\@!" doesn't match after that.
>
> I know why "a"  matches the pattern. but I don't understand why "ap"
> could match the pattern "a.\{-}p\@!", so does "aap".
> why "appppp" also matches the pattern?

It only matches if it has something after it that is not a "p".

The expanded pattern is

    a.....p\@!

The "a....." matches "appppp" and the "p\@!" ensures there is no "p"
coming next, though without including that character in the match.

> from the pattern "a.\{-}p\@!", I can tell:
> if the pattern is a.\{-}p, it will match ap, aaaap and
> absdfasdfasdasdfasdp since .\{-} could be 0 to more chars as few as
> possible, but followed with a p.

That's true. However "a.\{-}p" is not part of the pattern. The final "p"
has a different meaning because of the "\@!" following it.

"p\@!" is not the same as "[^p]". It does not match something that is
not a "p", it just checks that something that there isn't a "p" 'ready'
to be matched. Whatever is there (if anything) isn't actually matched.

> if \@! is after p, does it mean p should not appear at the end?

It means "p" should not appear *after* the end.

> why ap is ok?

It is only OK if it is in the context of something not followed by a
"p". So if you had the word "apt", the "ap" would match, because
"a.\{-}" matches "ap" and "p\@!" succeeds because "t" is not "p".

Does that help?

Smiles,

Ben.



--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Matches with zero width if the preceding atom does NOT match at the current position.

baumann Pan
In reply to this post by Ben Fritz
Thanks! still confused, could you explain more? or more examples? Thanks again!

On Fri, Aug 19, 2011 at 4:40 AM, Ben Fritz <[hidden email]> wrote:

>
>
> On Aug 18, 11:02 am, baumann Pan <[hidden email]> wrote:
>> Hi Gurus,
>>
>> I could not understand the descriptions below about the usage of \@!.
>>  "a.\{-}p\@!" will match any
>>         "a", "ap", "aap", etc. that isn't followed by a "p", because the "."
>>         can match a "p" and "p\@!" doesn't match after that.
>>
>> I know why "a"  matches the pattern. but I don't understand why "ap"
>> could match the pattern "a.\{-}p\@!", so does "aap".
>> why "appppp" also matches the pattern?
>>
>> from the pattern "a.\{-}p\@!", I can tell:
>> if the pattern is a.{-}p, it  will match ap, aaaap and
>> absdfasdfasdasdfasdp since .\{-} could be 0 to more chars as few as
>> possible,but followed with a p.
>> if\@! is after p, does it mean p should not appear at the end? why ap
>> is ok? adsfasdasdfap appp is matched the pattern  "a.\{-}p\@!"?????
>>
>
> 'a' matches because .\{-} could be zero characters
> 'ap' matches because .\{-} matches the p,
I don't think .\{-} will p, since \{-} is matching as few as possible.

>and then the next character
> is not a p, matching the p\@! with zero width. End-of-line is also
> "not a p" so that matches as well.
>
> The root of the problem is the use of the '.' character which also
> matches the p.
why . matches p? I don't understand since . is followed by \{-}, which
mean as few as possible,
so I think a.\{-} will only a, aa, aa, aaa, etc.

> If you want to rule out ap, aaap, etc. then you'd want
> a[^p]* or similar.
>
> --
> You received this message from the "vim_use" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Matches with zero width if the preceding atom does NOT match at the current position.

Benjamin R. Haskell-8
On Fri, 19 Aug 2011, baumann Pan wrote:

> Thanks! still confused, could you explain more? or more examples? Thanks again!
>
> On Fri, Aug 19, 2011 at 4:40 AM, Ben Fritz wrote:
>>
>>
>> On Aug 18, 11:02 am, baumann Pan wrote:
>>> Hi Gurus,
>>>
>>> I could not understand the descriptions below about the usage of \@!.
>>>  "a.\{-}p\@!" will match any
>>>         "a", "ap", "aap", etc. that isn't followed by a "p", because the "."
>>>         can match a "p" and "p\@!" doesn't match after that.
>>>
>>> I know why "a"  matches the pattern. but I don't understand why "ap"
>>> could match the pattern "a.\{-}p\@!", so does "aap".
>>> why "appppp" also matches the pattern?
>>>
>>> from the pattern "a.\{-}p\@!", I can tell:
>>> if the pattern is a.{-}p, it  will match ap, aaaap and
>>> absdfasdfasdasdfasdp since .\{-} could be 0 to more chars as few as
>>> possible,but followed with a p.
>>> if\@! is after p, does it mean p should not appear at the end?

No, it means that p should not appear *after* the end.


>>> why ap is ok? adsfasdasdfap appp is matched the pattern
>>> "a.\{-}p\@!"?????
>>>
>>
>> 'a' matches because .\{-} could be zero characters
>> 'ap' matches because .\{-} matches the p,
> I don't think .\{-} will p, since \{-} is matching as few as possible.
>
>> and then the next character
>> is not a p, matching the p\@! with zero width. End-of-line is also
>> "not a p" so that matches as well.
>>
>> The root of the problem is the use of the '.' character which also
>> matches the p.
> why . matches p? I don't understand since . is followed by \{-}, which
> mean as few as possible,
> so I think a.\{-} will only a, aa, aa, aaa, etc.

It sounds like you're misinterpreting "as few as possible".  It means
that it will match as few as possible while still:

1. matching as early in the string as possible

2. succeeding, if it can

It really just means that, if it has the option, it will stop at the
first match instead of keeping going until it finds the longest match.

Example of #1:
:echo matchstr('aab','a\{-}b')
echoes 'aab', not 'ab', because 'aab' starts earlier in the string than 'ab'.
(even though 'ab' has fewer 'a's)

Example of #2 is:
:echo matchstr('acaab','a\{-}b')
echoes 'aab', even though 'a' has fewer 'a's, because 'ac' doesn't match

Combining that with \@!, you have the pattern above:
a.\{-}p\@!

Input string:

appp
╵    - a=a, ''=.\{-}, but followed by p, so no match
└┘   - a=a, p=.\{-}, but followed by p, so no match
└─┘  - a=a, pp=.\{-}, but followed by p, so no match
└──┘ - a=a, ppp=.\{-}, not followed by p (followed by nothing), so match

--
Best,
Ben H

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Matches with zero width if the preceding atom does NOT match at the current position.

Ben Schmidt
In reply to this post by Ben Schmidt
I'm including the mailing list again, so others can see the answer and
perhaps help further.

On 19/08/11 2:24 PM, baumann Pan wrote:

> HI Ben,
> Thanks in advance.
> Still have question.
>
>>> from the pattern "a.\{-}p\@!", I can tell:
>>> if the pattern is a.\{-}p, it will match ap, aaaap and
>>> absdfasdfasdasdfasdp since .\{-} could be 0 to more chars as few as
>>> possible, but followed with a p.
>>
>> That's true. However "a.\{-}p" is not part of the pattern. The final "p"
>> has a different meaning because of the "\@!" following it.
>>
>> "p\@!" is not the same as "[^p]". It does not match something that is
>> not a "p", it just checks that something that there isn't a "p" 'ready'
>> to be matched. Whatever is there (if anything) isn't actually matched.
>>
>>> if \@! is after p, does it mean p should not appear at the end?
>>
>> It means "p" should not appear *after* the end.
> An example to explain the above? Thanks.

Well, consider the text "app". Since there is \{-} involved, we start
with the shortest potential match and lengthen it character by
character.

- "a" can be matched by "a.\{-}" (0 repeats of "."), but after the end
   of the match is "pp", so since "p" matches (the beginning of) that,
   "p\@!" causes the match to fail. So "a" does not match.

- "ap" can be matched by "a.\{-}" (1 repeat of "."), but after the end
   of the match is "p", so since "p" matches that, "p\@!" causes the
   match to fail. So "ap" does not match.

- "app" can be matched by "a.\{-}" (2 repeats of "."), and after the end
   of the match is nothing. "p" does not match nothing, so "p\@!" causes
   the match to succeed. So "app" matches.

Notice how the final decision about whether the text matches or not is
made by looking at what is after the actual match.

Also notice how the \{-} interacts with the \@! also. They don't act
independently. If the \@! causes the match to fail, the \{-} will still
keep trying longer matches until one succeeds.

>>> why ap is ok?
>>
>> It is only OK if it is in the context of something not followed by a
>> "p". So if you had the word "apt", the "ap" would match, because
>> "a.\{-}" matches "ap" and "p\@!" succeeds because "t" is not "p".
>>
> if the pattern is a.\{-}, the ap will not matched with the pattern,
> why ap could match the a.\{-}p\@!? what's the difference? Thanks!

Well, "a.\{-}" on its own won't match anything except "a" because the
smallest number of repeats of "." is always going to be zero. It is what
comes after that part of the pattern that restricts it. Because there is
"p\@!" after the ".\{-}", zero repeats will not work, because if you
used zero repeats, the thing after the end of the match would be "pt",
and that would match "p". So instead, we must use one repeat of ".",
match "ap" and have "t" after the end of the match, which doesn't match
"p" (so "\@!" succeeds).

> Could you give examples when p is amony a word, /a.\{-}\@! will not match.

I think you left out a "p" there in the pattern.

It is not really possible to find examples where "a.\{-}p\@!" does not
match. You can only find examples where it might not match what you
expect. Because, like the example above, you always get to the point
where "a.\{-}" matches everything, and "p\@!" succeeds because "p"
doesn't match nothing.

So, it matches

"ap" in "apt"
"app" in "apple"
"app" in "app"
"ap" in "ap"
"a" in "a"
"ap" in "apipe"
"a" in "airpipe"

If you remove the matching text from each of them, you will notice that
the bit that is left (the bit after the match) is always the first
position (after the first "a") that "p" does not match, so the smallest
number of repeats of "." that makes a success.

Ben.



--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Matches with zero width if the preceding atom does NOT match at the current position.

Ben Schmidt
In reply to this post by baumann Pan
>>> from the pattern "a.\{-}p\@!", I can tell:
[...]
>> 'a' matches because .\{-} could be zero characters
>> 'ap' matches because .\{-} matches the p,
> I don't think .\{-} will p, since \{-} is matching as few as possible.

"\{-}" doesn't just mean "as few as possible", it means "as few as
possible to make the whole pattern succeed".

If it didn't match the "p" the whole pattern would fail (because of the
"p\@!") so it does match the "p". It's a longer match, but it is the
shortest match that makes the whole pattern succeed.

(If you wanted "as few as possible regardless" you would use "\@>",
which basically divides a pattern up so that the pieces either side
behave independently. If the pattern were "a.\{-}\@>p\@!" then ".\{-}"
would always match nothing because that's the smallest match that can
succeed when there are not other restrictions. The whole pattern then
would behave the same as "ap\@!", i.e. it would match any "a" not
followed by a "p".)

Ben.

>> The root of the problem is the use of the '.' character which also
>> matches the p.
> why . matches p? I don't understand since . is followed by \{-}, which
> mean as few as possible,
> so I think a.\{-} will only a, aa, aa, aaa, etc.

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Matches with zero width if the preceding atom does NOT match at the current position.

baumann Pan
In reply to this post by Benjamin R. Haskell-8
Thanks lots!
the last paragraph is helpful for me! but the explaination of "as few
as possible"  is also of importance.


On Fri, Aug 19, 2011 at 1:32 PM, Benjamin R. Haskell <[hidden email]> wrote:

> On Fri, 19 Aug 2011, baumann Pan wrote:
>
>> Thanks! still confused, could you explain more? or more examples? Thanks
>> again!
>>
>> On Fri, Aug 19, 2011 at 4:40 AM, Ben Fritz wrote:
>>>
>>>
>>> On Aug 18, 11:02 am, baumann Pan wrote:
>>>>
>>>> Hi Gurus,
>>>>
>>>> I could not understand the descriptions below about the usage of \@!.
>>>>  "a.\{-}p\@!" will match any
>>>>         "a", "ap", "aap", etc. that isn't followed by a "p", because the
>>>> "."
>>>>         can match a "p" and "p\@!" doesn't match after that.
>>>>
>>>> I know why "a"  matches the pattern. but I don't understand why "ap"
>>>> could match the pattern "a.\{-}p\@!", so does "aap".
>>>> why "appppp" also matches the pattern?
>>>>
>>>> from the pattern "a.\{-}p\@!", I can tell:
>>>> if the pattern is a.{-}p, it  will match ap, aaaap and
>>>> absdfasdfasdasdfasdp since .\{-} could be 0 to more chars as few as
>>>> possible,but followed with a p.
>>>> if\@! is after p, does it mean p should not appear at the end?
>
> No, it means that p should not appear *after* the end.
>
>
>>>> why ap is ok? adsfasdasdfap appp is matched the pattern
>>>> "a.\{-}p\@!"?????
>>>>
>>>
>>> 'a' matches because .\{-} could be zero characters
>>> 'ap' matches because .\{-} matches the p,
>>
>> I don't think .\{-} will p, since \{-} is matching as few as possible.
>>
>>> and then the next character
>>> is not a p, matching the p\@! with zero width. End-of-line is also
>>> "not a p" so that matches as well.
>>>
>>> The root of the problem is the use of the '.' character which also
>>> matches the p.
>>
>> why . matches p? I don't understand since . is followed by \{-}, which
>> mean as few as possible,
>> so I think a.\{-} will only a, aa, aa, aaa, etc.
>
> It sounds like you're misinterpreting "as few as possible".  It means that
> it will match as few as possible while still:
>
> 1. matching as early in the string as possible
>
> 2. succeeding, if it can
>
> It really just means that, if it has the option, it will stop at the first
> match instead of keeping going until it finds the longest match.
>
> Example of #1:
> :echo matchstr('aab','a\{-}b')
> echoes 'aab', not 'ab', because 'aab' starts earlier in the string than
> 'ab'.
> (even though 'ab' has fewer 'a's)
>
> Example of #2 is:
> :echo matchstr('acaab','a\{-}b')
> echoes 'aab', even though 'a' has fewer 'a's, because 'ac' doesn't match
>
> Combining that with \@!, you have the pattern above:
> a.\{-}p\@!
>
> Input string:
>
> appp
> ╵    - a=a, ''=.\{-}, but followed by p, so no match
> └┘   - a=a, p=.\{-}, but followed by p, so no match
> └─┘  - a=a, pp=.\{-}, but followed by p, so no match
> └──┘ - a=a, ppp=.\{-}, not followed by p (followed by nothing), so match
>
> --
> Best,
> Ben H
>
> --
> You received this message from the "vim_use" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>

--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
Loading...