Hey Brad, thanks much for the explication:

> 「<!before .>」 should probably also prevent the position from being at the end.

> It does work if you write it differently

>     'abc' ~~ / b <!before( /./ )> /
>     Nil

That's pretty interesting, though I can't say I understand at all
what's going on there.

> It does seem like there could be a bug here.

That was my suspicion.  I'll probably open an issue on it soon.

> All of that said, I don't think it is useful to tell new Raku programmers 
> that you can use those features that way.

Yes, certainly not.  Just to be clear, I'm just messing around
with after/before to get a better sense of what they do.

I tried to avoid saying the two forms are equivalent, they just
do roughly similar things.



On 5/26/20, Brad Gilbert <b2gi...@gmail.com> wrote:
> I'm not sure that is the best way to look at 「<before>」 and 「<after>」.
>
>     > 'abcd123abcd' ~~ / <?before <digit>> .+ <?after <digit>> /
>     「123」
>
> In the above code 「<?before <digit>>」 makes sure that the first thing that
> 「.+」 matches is a 「<digit>」
> And 「<?after <digit>>」 makes sure that the last thing 「.+」 matches is also
> a 「<digit>」
>
> The 「<?before <digit>>」 is written in front of the 「.+」 so it starts at
> that position
>
> It does the thing that 「<digit>」 would normally do.
>
>     ' a b c d 1 2 3 a b c d '
>     ' _ _ _ _^1^_ _ _ _ _ _ '
>
> The thing is, 「<before>」 resets the position to what it was immediately
> before the successful 「<digit>」 match.
>
>     ' a b c d 1 2 3 a b c d '
>     ' _ _ _ _^_ _ _ _ _ _ _ '
>
> The 「.+」 then tries to grab everything
>
>     ' a b c d 1 2 3 a b c d '
>     ' _ _ _ _^1 2 3 a b c d^'
>
> Then  「<?after <digit>>」 gets to tell it that it can't do that.
>
> The reason is that 「<after>」 looks backwards from the current position. The
> current position is at the very end.
> It obviously isn't a 「<digit>」, so 「.+」 has to keep giving up characters
> until its last value is a 「<digit>」.
>
>     ' a b c d 1 2 3 a b c d '
>     ' _ _ _ _^1 2 3^_ _ _ _ '
>
> ---
>
> You can use 「<after>」 to check that is at the beginning.
>
>      'abc' ~~ / <!after .> b /
>      Nil
>
> The reason is that if the current position is anywhere other than the
> beginning 「.」 would match.
> Since we used 「!」 that won't fly.
>
> 「<!before .>」 should probably also prevent the position from being at the
> end.
>
> It does work if you write it differently
>
>     'abc' ~~ / b <!before( /./ )> /
>     Nil
>
> Note that 「<before>」 and 「<after>」 are really just function calls.
>
> It does seem like there could be a bug here.
>
> ---
>
> All of that said, I don't think it is useful to tell new Raku programmers
> that you can use those features that way.
>
> It make them think that these two regexes are doing something similar.
>
>     / ^ ... /
>     / <!after .> ... /
>
> They match the same three characters, but for entirely different reasons.
>
> The 「^」 version is basically the same as:
>
>     / <?{ $/.pos == 0 }> ... /
>
> While the other one is something like:
>
>     / <!{ try $/.orig.substr( $/.pos - 1, 1 ) ~~ /./ }> ... /
>
> (The 「try」 is needed because 「.substr( -1 )」 is a Failure.)
>
> So then these:
>
>     / ... $ /
>     / ... <!before .>
>
> Would be
>
>     / ... <?{ $/.pos == $/.orig.chars }> /
>     / ... <!{ try $/.orig.substr( $/.pos, 1 ) ~~ /./ }> /
>
> ---
>
> What I think is happening is that the 「<!after .>」 works because the
> 「.substr( -1, 1)」 creates a Failure.
>
> The thing is that 「'abc'.substr( 3, 1 )」 doesn't create a Failure, it just
> gives you an empty Str.
>
> (The second argument is the maximum number of characters to return.)
>
> On Mon, May 25, 2020 at 4:10 PM Joseph Brenner <doom...@gmail.com> wrote:
>
>> Given this string:
>>    my $str = "Romp romp ROMP";
>>
>> We can match just the first or last by using the usual pinning
>> features, '^' or '$':
>>
>>    say $str ~~ m:i:g/^romp/;               ## (「Romp」)
>>    say $str ~~ m:i:g/romp$/;               ## (「ROMP」)
>>
>> Moritz Lenz (Section 3.8 of 'Parsing', p32) makes the point you
>> can use 'after' to do something like '^' pinning:
>>
>>    say $str ~~ m:i:g/ <!after .> romp /;   ## (「Romp」)
>>
>> That makes sense:  the BOL is "not after any character"
>> So: I wondered if there was a way to use 'before' to do
>> something like '$' pinning:
>>
>>   say $str ~~ m:i:g/ romp <!before .> /;  ## (「Romp」 「romp」)
>>
>> That was unexpected: it filters out the one I was trying to
>> match for, though the logic seemed reasonable: the EOL is "not
>> before any character".
>>
>> What if we flip this and do a positive before match?
>>
>>   say $str ~~ m:i:g/ romp <?before .> /;  ## (「Romp」 「romp」)
>>
>> That does exactly the same thing, but here the logic makes
>> sense to me: the first two are "before some character",
>> but the last one isn't.
>>
>

Reply via email to