Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Help with pattern matching quantifiers

by Anonymous Monk
on Oct 24, 2016 at 17:42 UTC ( [id://1174610]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks
I want to perform a pattern matching, but it seems that I have some problems capturing the desired patterns. Consider the following lines from a matrix
-8-18 -9-10 -8 -7 -9-10 -9 -6 -5 -8 12 -7-10 -8 -8 -8 -8 -6 -3 2 2 -2 -8 1 -2 -5 -1 -4 -6 6 -4 -6 -5 -1 0 -8 -6 -6 3 -6 -3 -6 -2 -5 -5 -5 -4 4 -3 -2 -2 -3 -5 1 3 -7 -4 3 1 -6 -5 -6 4 -5 -6 -5 -6 3 1 -5 -3 -2 -5 -1 3 -4 -3 4 2 -8 -6 -7 -8 -8 -8 7 -8 -9 -9 -7 -8 -6 -8 -4 -7 -9 -9 -8

I want to capture every number (negative or positive), but as you can see, although the obvious separator is the space, sometimes the numbers are next to each other.
I tried this:
if($all_matrix_competitor=~/^([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+) +\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0, +5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\ +d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+ +)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0,5}([\d\-]+)\s{0 +,5}[\d\-]+\s+/)

because I thought the \s{0,5} means  match space 0 up to 5 times, but it doesn't work...
Can you help me fix this?

Replies are listed 'Best First'.
Re: Help with pattern matching quantifiers
by toolic (Bishop) on Oct 24, 2016 at 17:55 UTC
    Since your lines are fixed-width, you can use unpack:
    use warnings; use strict; while (<DATA>) { chomp; my $template = 'A3' x 20; my @nums = unpack $template, $_; } __DATA__ -8-18 -9-10 -8 -7 -9-10 -9 -6 -5 -8 12 -7-10 -8 -8 -8 -8 -6 -3 2 2 -2 -8 1 -2 -5 -1 -4 -6 6 -4 -6 -5 -1 0 -8 -6 -6 3 -6 -3 -6 -2 -5 -5 -5 -4 4 -3 -2 -2 -3 -5 1 3 -7 -4 3 1 -6 -5 -6 4 -5 -6 -5 -6 3 1 -5 -3 -2 -5 -1 3 -4 -3 4 2 -8 -6 -7 -8 -8 -8 7 -8 -9 -9 -7 -8 -6 -8 -4 -7 -9 -9 -8

    I added a single space to the beginning of every line so that each number would occupy 3 columns. If that is not the case with your actual input, the template just needs to be adjusted.

      Oh wow, I did not know this command!!
      Thank you very much!
Re: Help with pattern matching quantifiers
by tybalt89 (Monsignor) on Oct 24, 2016 at 18:11 UTC

    Just regex for what you want...

    #!/usr/bin/perl # http://perlmonks.org/?node_id=1174610 use strict; use warnings; while(<DATA>) { my @values = /-?\d+/g; print "@values\n"; } __DATA__ -8-18 -9-10 -8 -7 -9-10 -9 -6 -5 -8 12 -7-10 -8 -8 -8 -8 -6 -3 2 2 -2 -8 1 -2 -5 -1 -4 -6 6 -4 -6 -5 -1 0 -8 -6 -6 3 -6 -3 -6 -2 -5 -5 -5 -4 4 -3 -2 -2 -3 -5 1 3 -7 -4 3 1 -6 -5 -6 4 -5 -6 -5 -6 3 1 -5 -3 -2 -5 -1 3 -4 -3 4 2 -8 -6 -7 -8 -8 -8 7 -8 -9 -9 -7 -8 -6 -8 -4 -7 -9 -9 -8
      Ah damn, I missed that!
      But thanks a lot!
Re: Help with pattern matching quantifiers
by ww (Archbishop) on Oct 24, 2016 at 19:14 UTC

    ... or just use split:

    #!/usr/bin/perl use strict; use warnings; use 5.018; #1174610 my $data="-8-18 -9-10 -8 -7 -9-10 -9 -6 -5 -8 12 -7-10 -8 -8 -8 -8 -6 -3 2 2 -2 -8 1 -2 -5 -1 -4 -6 6 -4 -6 -5 -1 0 -8 -6 -6 3 -6 -3 -6 -2 -5 -5 -5 -4 4 -3 -2 -2 -3 -5 1 3 -7 -4 3 1 -6 -5 -6 4 -5 -6 -5 -6 3 1 -5 -3 -2 -5 -1 3 -4 -3 4 2 -8 -6 -7 -8 -8 -8 7 -8 -9 -9 -7 -8 -6 -8 -4 -7 -9 -9 -8"; my @data = split(/ +/,$data); my $i=1; for my $item(@data) { if ( $item =~/\d+-\d+/ ) { $item =~ s/(-\d+)/ $1/g; if ($i == 38 ) { print "\n$item "; $i = 1; }else{ print "$item "; $i = $i+3; } }else{ if ($i == 38 ) { print "\n$item "; $i = 1; }else{ print "$item "; $i = $i+3; } } } =head C:\> 1174610.pl -8 -18 -9 -10 -8 -7 -9 -10 -9 -6 -5 -8 12 -7 -10 -8 -8 + -8 -8 -6 -3 2 2 -2 -8 1 -2 -5 -1 -4 -6 6 -4 -6 -5 -1 0 -8 -6 + -6 3 -6 -3 -6 -2 -5 -5 -5 -4 4 -3 -2 -2 -3 -5 1 3 -7 +-4 3 1 -6 -5 -6 4 -5 -6 -5 -6 3 1 -5 -3 -2 -5 -1 3 -4 - +3 4 2 -8 -6 -7 -8 -8 -8 7 -8 -9 -9 -7 -8 -6 -8 -4 -7 -9 + -9 -8 =cut

    But the preceding reply (Re: Help with pattern matching quantifiers from tybalt89) is preferable, both for use of  __DATA__ and for the consistency of spacing between values in the output.

    But it intrigued me to write the extra code to hold line lengths to a relatively narrow page or screen.

      #!/usr/bin/perl use strict; use warnings; while(<DATA>) { my @values = map { split /\d\K\b/ } split ' '; print "@values\n"; } __DATA__ -8-18 -9-10 -8 -7 -9-10 -9 -6 -5 -8 12 -7-10 -8 -8 -8 -8 -6 -3 2 2 -2 -8 1 -2 -5 -1 -4 -6 6 -4 -6 -5 -1 0 -8 -6 -6 3 -6 -3 -6 -2 -5 -5 -5 -4 4 -3 -2 -2 -3 -5 1 3 -7 -4 3 1 -6 -5 -6 4 -5 -6 -5 -6 3 1 -5 -3 -2 -5 -1 3 -4 -3 4 2 -8 -6 -7 -8 -8 -8 7 -8 -9 -9 -7 -8 -6 -8 -4 -7 -9 -9 -8
      Or split by any num of spaces, and additionally split with zero-length matches (find decimal, don't grab previous, find word bound. (e.g.: '-8-18' -> ('-8', '-18')).

      Look, that your regex ([\d\-]+) will take both numbers '-8-18' into $1.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1174610]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-04-19 23:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found