2014-12-10 3 views
1

У меня есть следующий кодКак получить это расширенное регулярное выражение perl для работы?


my @txt = ("Line 1. [foo] bar", 
      "Line 2. foo bar", 
      "Line 3. foo [bar]" 
     ); 
my $regex = qr/^ 
       Line  # Bare word 
       (\d+)\. # line number 
       \[  # Open brace 
       (\w+) # Text in braces 
       ]  # close brace 
       .*  # slurp 
       $ 
       /x; 

my $nregex = qr/^\s*Line\s*(\d+)\.\s*\[\s*(\w+)\s*].*$/; 

foreach (@txt) { 
    if ($_ =~ $regex) { 
     print "Lnum $1 => $2\n"; 
    } 

    if ($_ =~ $nregex) { 
     print "N Lnum $1 => $2\n"; 
    } 
} 

Выходной

N Lnum 1 => foo 

Я ожидаю оба regexs эквивалентными и захватить только первую строку массива. Однако работает только $nregex!

Как можно установить $regex так, чтобы он работал одинаково (с опцией x)?


Редактировать

На основании ответа, обновила регулярное выражение, и она работает.

my $regex = qr/^  \s* 
       Line \s* # Bare word 
       (\d+)\. \s* # line number 
       \[  \s* # Open brace 
       (\w+) \s* # Text in braces 
       ]  \s* # close brace 
       .*   # slurp 
       $ 
       /x; 
+2

Попробуйте написать тот же шаблон. –

+1

С '/ x' ваши пробелы ничтожны. Если вы хотите совместить пробелы, вам нужно использовать '[] *' или '\ s *' или некоторые такие, как и в другом регулярном выражении. – tripleee

+0

Если это все, что вы хотите сделать, суффикс '. * $' Лишний. Конечно, если вы выполняете сопоставление в цикле и вам нужна следующая попытка начать с начала строки, это может быть полезно (но привязка к '^' уже позаботится об этом). – tripleee

ответ

4

Ваши два выражения НЕ совпадают. Вы должны иметь бит \ s * в первом./X позволяет писать аккуратно отформатированные выражения - с комментариями, как вы заметили. Таким образом, пробелы в версии/x не считаются значимыми и не будут способствовать какой-либо соответствующей деятельности.

Другими словами, ваш/х версия является эквивалентом

qr/^Line(\d+)\.\[(\w+)].*$/x 

Кстати, просто имея простое пространство вместо \ S * или \ S + также потерпеть неудачу много раз; ваши образцы данных содержат два пробела рядом друг с другом в нескольких местах. Эти два места не будут соответствовать одному пространству.

Окончательный совет: если вы должны иметь хотя бы одно место в определенном месте, вы должны использовать \ s + для обеспечения хотя бы одного места. Вы можете точно определить, где это может быть полезно в ваших шаблонах, как только вы это узнаете.