How to remember a match and its position in an array in Perl?

Please, help

I am working with a file whose data lines look like below. As you can see, the data is divisible by 4 by " |||

", so I will have four arrays (if I parse it). I want this:

  • I want to check if there are punctuation marks in the first array, if any, remember the position in the array.
  • Go to the same position in the third array and read the number in parenthesis.
  • Check if the value at the index of the number array is punctuation.

My problem is that I couldn't remember the match and its position! Can you help here?

útil por la unión europea, a ||| by the european union, ||| () (0) (1) (3) (2) (4) () ||| (1) (2) (4) (3) (5)
+1


a source to share


3 answers


In addition to pos()

there @-

and @+

:



#!/usr/bin/perl

use strict;
use warnings;

my $string = "foo bar baz";

if ($string =~ /(foo) (bar) (baz)/) {
    print "the whole match is between $-[0] and $+[0]\n",
        "the first match is between $-[1] and $+[1]\n",
        "the second match is between $-[2] and $+[2]\n",
        "the third match is between $-[3] and $+[3]\n";
}   

      

+5


a source


The function pos()

can be used to report (end) the position of the match. Example:

my $string = 'abcdefghijk';

if($string =~ /e/g)
{
  print "There is an 'e' ending at position ", pos($string), ".\n";
}

      

This code will print: "There is an e at position 5. (Positions start at 0.) Combine that with the usual use of parentheses and you should be able to solve your problem.



In addition to pos()

there are also special global arrays @-

and @+

that provide the start and end offsets for each subpattern. Example:

my $string = 'foo bar baz';

if($string =~ /(foo) (bar) (baz)/)
{
  print "The whole match is between $-[0] and $+[0].\n",
        "The first match is between $-[1] and $+[1].\n",
        "The second match is between $-[2] and $+[2].\n",
        "The third match is between $-[3] and $+[3].\n";
}

      

(Thanks Chas. Owens for keeping this in mind, I looked in perlre

for them instead perlvar

)

+4


a source


If you have something to do in your code that's not easy, it's best to break it down into discrete steps and variables so that it's easy to understand.

So I would first split the data string into four parts:

#The data record
my $dataRec = "útil por la unión europea , a ||| by the european union , ||| () (0) (1) (3) (2) (4) () ||| (1) (2) (4) (3) (5)";

#split it into four parts
my ($Native, $English, $data1, $data2) = split(/\|\|\|/,$dataRec);

#Store the position of the punctuation mark
my $puncPos = index($Native, ",");

#If we found the punctuation mark, parse the data
my @dataList;
my $dataValue;
if ( $puncPos != -1 )
   {
   @dataList = split(/[)( ]/,$data1);

   # use the punctuation position as the index into the array of values parsed
   $dataValue = $dataList[$puncPos];
   }

      

Something like that...

+1


a source







All Articles