2013-08-19 2 views
2

У меня есть переменный содержит: No such file or directory at ./EMSautoInstall.pl line 50.Регулярного выражения группировки в Perl

Я хочу создать переменный содержит No such file or directory и еще один содержит at ./EMSautoInstall.pl line 50.

моего REGEX является: my ($eStmnt, $lineNO) = $! =~ /(.*[^a][^t])(.*)/;

при печати как переменные, то первый содержит No such file or directory, но второй пуст.

Почему это происходит?

+1

Для общей поддержки регулярных выражений Perl, начинайте с 'perldoc perlrequick', и когда вы его победите, переходите к' perldoc perlre'. – ThisSuitIsBlackNot

ответ

7

У вас действительно есть ли строка в переменной $!? Потому что обычно, at line... часть добавляется die и warn. Я подозреваю, что вы просто

$! = "No such file or directory"; 

И ваше регулярное выражение соответствует, потому что это позволяет пустой строке

/(.*[^a][^t])(.*)/ 

Т.е. второй захват также не соответствует нишу, и первым захватом может быть все, что не заканчивается at.

Для подтверждения

print $!; 

Если печать No such file or directory.

+0

Да, вы правы :) –

+2

@M_E Тайна решена. :) В случае сомнений модуль 'Data :: Dumper' является хорошим инструментом для отладки:' print Dumper $ variable'. – TLP

+1

+1, хорошая детективная работа – Zaid

1

Вы можете использовать это:

((?:[^a]+|\Ba|a(?!t\b))+)(.*) 

идея заключается в том, чтобы соответствовать все, что не является «а» или «а», которая не является частью слова «в»

детали :

(    # first capturing group 
    (?:   # open a non capturing group 
     [^a]+  # all that is not a "a" one or more times 
     |   # OR 
     \Ba  # a "a" not preceded by a word boundary 
     |   # OR 
     a(?!t\b) # "a" not followed by "t" and a word boundary 
    )+   # repeat the non capturing group 1 or more times 
)     # close the capturing group 
(.*)    # the second capturing group 

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

((?>[^a]++|\Ba|a(?!t\b))++)(.*+) 
+0

Не могли бы вы объяснить это, пожалуйста? Это первый раз, когда я вижу это, потому что я новичок в Perl. –

+0

Спасибо alot @Casimir et Hippolyte –

+0

Я хочу спросить вас, откуда я могу получить эти знания REGEX –

2

Использование split здесь с опережением утверждением имеет больше смысла, чем регулярные выражения захватов:

my ($eStmnt, $lineNO) = split /(?=at)/, $!; 
+0

В чем смысл «? =»? –

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