简体   繁体   中英

Perl: Matching 3 pairs of numbers from 4 consecutive numbers

I am writing some code and I need to do the following:

Given a 4 digit number like "1234" I need to get 3 pairs of numbers (the first 2, the 2 in the middle, and the last 2), in this example I need to get "12" "23" and "34".

I am new to perl and don't know anything about regex. In fact, I am writing a script for personal use and I've started reading about Perl some days ago because I figured it was going to be a better language for the task at hand (need to do some statistics with the numbers and find patterns)

I have the following code but when testing I processed 6 digit numbers, because I "forgot" that the numbers I would be processing are 4 digits, so it failed with the real data, of course

foreach $item (@totaldata)
{
    my $match;

    $match = ($item =~ m/(\d\d)(\d\d)(\d\d)/);

    if ($match) 
    { 
    ($arr1[$i], $arr2[$i], $arr3[$i]) = ($item =~ m/(\d\d)(\d\d)(\d\d)/);
    $processednums++; 
    $i++;
    }
}

Thank you.

You can move last matching position with pos()

pos directly accesses the location used by the regexp engine to store the offset, so assigning to pos will change that offset..

my $item = 1234;

my @arr;
while ($item =~ /(\d\d)/g) {
  push @arr, $1;
  pos($item)--;
}
print "@arr\n"; # 12 23 34

The simplest way would be to use a global regex pattern search

It is nearly always best to separate verificaton of the input data from processing , so the program below first rejects any values that are not four characters long or that contain a non-digit character

Then the regex pattern finds all points in the string that are followed by two digits, and captures them

use strict;
use warnings 'all';

for my $val ( qw/ 1234 6572 / ) {

    next if length($val) != 4 or $val =~ /\D/;

    my @pairs = $val =~ /(?=(\d\d))/g;
    print "@pairs\n";
}

output

12 23 34
65 57 72

Here's a pretty loud example demonstrating how you can use substr() to fetch out the portions of the number, while ensuring that what you're dealing with is in fact exactly a four-digit number.

use warnings;
use strict;

my ($one, $two, $three);

while (my $item = <DATA>){
    if ($item =~ /^\d{4}$/){
        $one   = substr $item, 0, 2;
        $two   = substr $item, 1, 2;
        $three = substr $item, 2, 2;
        print "one: $one, two: $two, three: $three\n";
    }
}

__DATA__
1234
abcd
a1b2c3
4567
891011

Output:

one: 12, two: 23, three: 34
one: 45, two: 56, three: 67
foreach $item (@totaldata) {
    if ( my @match = $item =~ m/(?=(\d\d))/ ) {
        ($heads[$i], $middles[$i], $tails[$i]) = @match;
        $processednums++; 
        $i++;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM