Как запомнить совпадение и его положение в массиве в Perl? - PullRequest
1 голос
/ 16 мая 2009

Пожалуйста, помогите

Я работаю с файлом, строки данных которого выглядят так, как показано ниже. Как видно, данные делятся на 4 на |||, поэтому у меня будет четыре массива (если я их разделю). то, что я хочу, это:

  1. Я хочу проверить, есть ли знаки препинания в первом массиве, если он есть, запомните позицию в массиве.
  2. Перейдите в ту же позицию в третьем массиве и прочитайте число в скобках.
  3. Проверьте, является ли значение в индексе массива числа пунктуацией.

Моя проблема в том, что я не мог вспомнить матч и его позицию! Вы можете помочь здесь, пожалуйста?

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

Ответы [ 3 ]

5 голосов
/ 16 мая 2009

В дополнение к pos() есть @- и @+:

#!/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";
}   
4 голосов
/ 16 мая 2009

Функция pos() может использоваться для сообщения (конечной) позиции матча. Пример:

my $string = 'abcdefghijk';

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

В этом коде будет напечатано: "E 'заканчивается в позиции 5." (Позиции начинаются с 0.) Добавьте к этому обычное использование скобок, и вы сможете решить свою проблему.

В дополнение к pos() существуют также специальные глобальные массивы @- и @+, которые обеспечивают начальное и конечное смещения каждый подшаблон соответствует. Пример:

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";
}

( Спасибо Чэсу. Оуэнсу за пробежку по памяти; я искал в них perlre вместо них в perlvar)

1 голос
/ 16 мая 2009

Если в коде есть что-то непростое, лучше разбить его на отдельные шаги и переменные, чтобы их было легко понять.

Итак, я бы сначала разбил строку данных на четыре части:

#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];
   }

Что-то в этом роде ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...