El sáb, 30 ene 2021 a las 7:24, ToddAndMargo via perl6-users (<
perl6-us...@perl.org>) escribió:

> Hi All,
>
> rakudo-pkg-2020.12-01.x86_64
>
> Why does this work?
>
>  > $x = "1.33.222.4";
> 1.33.222.4
>  > $x ~~ m/ (<:N>+) [.] (<:N>+) [.] (<:N>+) [.] (<:N>+) /;
> 「1.33.222.4」
>   0 => 「1」
>   1 => 「33」
>   2 => 「222」
>   3 => 「4」
>

This works because you have the right amount of capturing groups  (<:N>+) (
https://docs.raku.org/language/regexes#capturing )separated by the right
amount of single characters (. matches a single character, check
https://docs.raku.org/language/regexes#Wildcards) It also works because
<:N> matches the unicode property number (
https://docs.raku.org/language/regexes#Unicode_properties), which includes
all kinds of numbers. If you are not going to use Balinese or Roman
numerals, it's probably OK if you use \d instead. Then, the string you're
matching (shown above) matches precisely the 4 groups there are. So ti
works. You probably want this instead:

say "1.33.222.4" ~~ m/(\d+) "." (\d+) "." (\d+) "." (\d+) /
「1.33.222.4」
 0 => 「1」
 1 => 「33」
 2 => 「222」
 3 => 「4」

Or, even better,

say "1.33.222.4" ~~ m/(\d+) ** 4 % "." /

Which uses the modified quantifier (
https://docs.raku.org/language/regexes#Modified_quantifier:_%,_%%) together
with a general quantifier
https://docs.raku.org/language/regexes#General_quantifier:_**_min..max
saying "I want this (\d+) exactly four times (** 4 ) separated by (%) a
literal dot "."".


>
>
> But this does not?
>     --> Why the wrong number in $2?
>     --> Why no Nil for $3?
>
>  > $x = "1.33.222";
> 1.33.222
>  > $x ~~ m/ (<:N>+) [.] (<:N>+) [.] (<:N>+) [.] (<:N>+) /;
>

Because [.] is "a non-grouping class of characters that includes any
character". So <:N> is matching the first 2, then [.] is matching any
character, so matching and dropping (
https://docs.raku.org/language/regexes#Non-capturing_grouping) the second
one, and then the last group of <:N> is capturing the last one. It would
fail if you had had 2 digits, instead of three.

This works and matches both strings.

say $_ ~~ /(\d+) ** {3..4} % "\."/ for <1.33.222.4 1.33.222>

「1.33.222.4」
 0 => 「1」
 0 => 「33」
 0 => 「222」
 0 => 「4」
「1.33.222」
 0 => 「1」
 0 => 「33」
 0 => 「222」

Once again, the regex tutorial is your friend
https://docs.raku.org/language/regexes, as well as the reference for Regex
or any of the other operators.

Cheers

-- 
JJ

Reply via email to