2013-03-31 6 views
1

Я пробовал следующие два сценария. Сценарий 1 получил результат, которого я ожидал. Сценарий 2 не был - вероятно, застрял в цикле while?не мог выбраться из цикла while?

$_= "Now we are engaged in a great civil war; we will be testing whether 
that nation or any nation so conceived and so dedicated can long endure. "; 

my $count = 0; 
while (/we/ig){ 
    $count++ 
    }; 
print $count; 

Выход 2

$_= "Now we are engaged in a great civil war, we will be testing whether 
that nation or any nation so conceived and so dedicated can long endure"; 

my $count = 0; 
while (/we/){ 
    $count++ 
    }; 
print $count; 

Мое понимание /g позволяет глобальное согласование. Но мне просто интересно, что сценарий 2, после того, как Perl находит первый матч «мы» в $_ и $count теперь равен 1, когда он возвращается назад, так как нет /g, как он реагирует? Или он застревает именно потому, что он НЕ знает, как реагировать?

+0

то, что возвращает матч зависит от трех вещи:/g или нет, контекст списка или нет, и есть ли захват parens (все описано в документации) – ysth

ответ

3

Регулярное выражение

/we/g 

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

/we/ 

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

my $count; 
while (/(.*?we)/) { 
    print "$1\n"; 
    exit if $count++ > 100; # don't spam too much 
} 

Если все, что вы хотите сделать, это сосчитать матчи, вы можете сделать что-то вроде этого:

my $count =() = /we/g; 

Или

my @matches = /we/g; 
my $count = @matches; 
+0

Спасибо большое! Нужно научиться проверять мои гипотезы :) –

+0

Добро пожаловать. – TLP

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