On 1/30/21 1:03 AM, William Michels via perl6-users wrote:
Hi Todd (and JJ),

On Fri, Jan 29, 2021 at 11:58 PM JJ Merelo <jjmer...@gmail.com> wrote:



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

Following on from JJ's excellent example:

say "1.33.222.4" ~~ m/(\d+) ** 3..4 % "." /
「1.33.222.4」
  0 => 「1」
  0 => 「33」
  0 => 「222」
  0 => 「4」
say "1.33.222" ~~ m/(\d+) ** 3..4 % "." /
「1.33.222」
  0 => 「1」
  0 => 「33」
  0 => 「222」
say "1.33" ~~ m/(\d+) ** 3..4 % "." /
False


HTH, Bill.



Hi Bill (and JJ),

My mistake was think that if a value at the end
did not exist, I was given back a null.  Now I know
to look for a false.

> say "1.33" ~~ m/(\d+) ** 3..4 % "." /
False

And in my application, I cooked its goose with

> say "1.33" ~ ".0.0.0.0.0" ~~ m/(\d+) ** 3..4 % "." /
「1.33.0.0」
 0 => 「1」
 0 => 「33」
 0 => 「0」
 0 => 「0」

Thank you!

-T

Reply via email to