2013-03-19 2 views
0

У меня есть следующий файл:Perl разделить с регулярным выражением для получения значений в массиве

id001 word1(100);"word2"(100);"word3"(98);"word4"(98);"word5"(94);word6; 
id002 word1(100);word7(100);word8(100);word9(100);word10;word11; 

Я хочу разделить каждый строк моего файла, чтобы получить идентификатор (= id00x), VAL (= wordX) и INT (= 100) в массиве. Мой код:

my @fields = split /[\t();"]"?/, $line; 
$id = $fields[0]; 
for (my $i = 1; $i < @fields; $i +=2) 
{ 
    $val=$fields[$i]; 
    $int=$fields[$i+1] 
} 

я получить только идентификатор и Вэл, которые не являются между двойным quote.Please вы можете дать мне несколько потенциальных клиентов?

+2

'$ fields [i]' wil l ссылаются на '$ fields [0]', и если вы не используете 'use warnings', это не скажет вам, почему. – TLP

+0

да, я забыл доллары! – Tof

+0

Добавить 'use strict; использовать предупреждения, 'к вашему скрипту и исправить любые ошибки и предупреждения. Используйте 'use Data :: Dumper' и' print Dumper \ @ fields', чтобы узнать, каков результат вашего раскола. – TLP

ответ

2

Проблема здесь является регулярное выражение. Вы можете проверить это, поместив в петлю сразу же после того, как делать раскол, как это:

my @fields = split /[\t();"]"?/, $line; 
    $id = $fields[0]; 
    foreach my $field(@fields) { 
    print("field is $field\n"); 
    } 

Это покажет вам, что у вас есть несколько пустых полей, и именно поэтому вы ничего в ваших переменных не получить. Причиной пустых полей является то, что регулярное выражение позволяет любому из перечисленных символов действовать как граница слова, поэтому, когда у вас более одного из них подряд, они будут вызывать несколько последовательных разрывов.

Я бы облегчил это, не пытаясь разделить всю строку сразу, Вместо этого я начал бы разбивать линию на более мелкие части и затем использовать регулярное выражение для извлечения частей. Вот мое предложение:

my @fields = split /[\t;]/, $line; 
$id = $fields[0]; 
for (my $i = 1; $i < $#fields; $i++) 
    { 
    ($val, $int) = $fields[$i] =~ /\"?(\w+)\"?\((\d+)\)/; 
    print("val is $val, int is $int\n"); 
    } 

Также обратите внимание, что способ получить количество объектов в массиве $#arrayname, не @arrayname. Последний также работает в скалярном контексте, но это плохая привычка.


Ниже здесь оригинальный ответ, который был только о синтаксисе

Здесь, по крайней мере одна ошибка:

$val=$fields[i]; 
$int=$fields[i+1] 

Вы должны использовать $ перед i, а также, как так:

$val=$fields[$i]; 
$int=$fields[$i+1] 
+0

да, я забыл доллары! – Tof

+2

Я программировал perl почти 20 лет. Я все еще скучаю по вещам как это иногда ...и всегда легче найти ошибки в чужом коде, чем в своих собственных. –

+0

но это не то, что моя ошибка !! – Tof

Смежные вопросы