2014-11-04 3 views
0

У меня есть входной файл, который не может быть искажен, и я просто хотел бы проверить и увидеть, что файл хорошо сформирован, прежде чем приступать к вычислениям программы. Для этого входного файла чтение его по строкам будет работать, так как мне нужно только проверить начало каждой строки.Проверьте, соответствует ли определенная часть строки другой строке в Perl

input.txt:

Data1: 30 
Data2: 20 
Data3: 50 

В принципе, я хочу, чтобы прочитать эту строку за строкой, и убедитесь, что каждая строка начинается с "Data1:" или "data2:" или "Data3:", и ничего больше. Другими словами, я могу предположить, что то, что будет после этого, будет целым (в этом случае нет возможности для него, в контексте этого приложения). Однако, если начало строки не начинается с одного из них, тогда мне нужно немедленно остановиться, чтобы не упустить ничего.

Я думаю, мне нужно использовать функцию индекса и проверить, что индекс этой подстроки находится в позиции 0 (т.е. в самом начале строки). Или, возможно, мне нужно использовать регулярное выражение.

Try Номер 1:

if (index($str, $substr) == 0) { 
    print "$str contains $substr\n"; 
} 

Try номер 1 был неправ. Это осложняло ситуацию. Я должен использовать здесь регулярное выражение.

Try Номер 2:

open my $in, '<', 'in.txt'; 
$iteration = 0 
while(<$in>){ 
    chomp; 
    next if /\s*(?:#|$)/; //Skip over lines starting with # or empty lines. 
    if($iteration==0) { 
     die "Error in file formatting!\n" unless /^Data1: [a-Z]+/; 
     my ($data1) = /Data[1]: ([a-z0-9-]+)\s*/; 
     $iteration++; 
    } 
    else if($iteration==1) { 
     die "Error in file formatting!\n" unless /^Data2: \d+/; 
     my ($data2) = /Data[2]: (\d+)/; 
     $iteration++; 

    } 
    else if($iteration==2) { 
     die "Error in file formatting!\n" unless /^Data3: \d+/; 
     my ($data3) = /Data[3]: (\d+)/; 
     $iteration=0; 

    } 
} 

ответ

1

Предполагая текущую строку в $_:

/^Data[123]: \d+/ or die; 

Проверят строка начинается с Data, цифры от 1 до 3, двоеточие, пробел и положительное целое число.

Если линия находится в $str, и если вам нужно сообщение об ошибке, синтаксис:

$str =~ /^Data[123]: \d+/ or die "Invalid line: $str"; 

Если вам нужно извлечь значения, изменить шаблон, чтобы:

/^Data([123]): (\d+)/ 

Значения будут в переменных $1 и $2 после матча.

Пропуск строк комментария будет столь же легко, как:

next if /^\s*(?:#|$)/; 

Это будет проверять, если первый непробельным символ строки является # или строка пуста.

+0

Хорошо, я возьму это и сделаю еще одну попытку. – Musicode

+0

Я не понимаю, как значение будет помещено в переменные $ 1 и $ 2 после матча ... – Musicode

+1

@Musicode Если вы заключите часть шаблона в круглые скобки, вы получаете * захватывающие группы *. Perl поставит значение, захваченное первым подшаблотелем в скобках в '$ 1', второе в' $ 2' и так далее.Подробнее см. В [perlre] (http://perldoc.perl.org/perlre.html). –

1

Использование индекса - это грязный способ достижения того, что, как я думаю, вам нужно. Это будет считаться в вашем файле и обрабатывать его по очереди, выходя из цикла, если строка не начинается с «Data1», «Data2» или «Data3» (печать только иллюстрирует точку):

use strict; 
use warnings; 

open my $in, '<', 'in.txt'; 

    while(<$in>){ 
    chomp; 
    next if /^#/; # Will skip the line if it begins with # 
    my ($number) = /Data[123]: (\d+)/; # Assigns the integer that follows Data1/2/3 to the scalar `$number` 
    die unless /^Data[123]/; # Exit loop if line doesn't begin with Data1/2/3 
    print "$number\n"; 
} 
+0

Хорошо, это хорошо, но у меня есть несколько вопросов об этом ответе. Что делать, если я хочу пропустить любые прокомментированные строки во входном файле? Поэтому, если строка начинается с «#», я бы пропустил ее. Во-вторых, как мне получить доступ к самому целочисленному значению после начала каждой строки? Кажется, я бы пропустил это. – Musicode

+0

@Musicode - см. Обновление – fugu

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