Когда это полезное приложение \G в регулярном выражении?
Я не понимаю, как использовать/нужен оператор \G
.
Я читал в perldoc:
Вы используете привязку \G для запуска следующего совпадения в той же строке, где последнее совпадение осталось.
Я не понимаю этого утверждения. Когда мы используем \G
, мы обычно переходим к символу после последнего матча.
Как показывает пример:
$_ = "1122a44";
my @pairs = m/(\d\d)/g; # qw( 11 22 44 )
Затем он говорит:
Если вы используете якорь \G, вы вынуждаете матч после 22, чтобы начать с a:
$_ = "1122a44";
my @pairs = m/\G(\d\d)/g;
Регулярное выражение не может соответствовать, поскольку оно не найти цифру, поэтому следующее совпадение не удастся и оператор соответствия вернется пары, которые он уже нашел
Я тоже этого не понимаю. "Если вы используете якорь \G, вы вынудите матч после 22, чтобы начать с." Но без \G совпадение будет пытаться в a
в любом случае правильно? Так в чем смысл этого предложения?
Я вижу, что в примере единственные пары напечатаны 11 и 22. Поэтому 44 не пробовали.
В этом примере также показано, что с помощью параметра c
он делает индекс 44 после этого.
Честно говоря, из всего этого я не могу понять, в чем польза этого оператора и когда он должен применяться.
Может кто-нибудь, пожалуйста, помогите мне понять это, возможно, с содержательным примером?
Обновление
Я думаю, что я не понял этого ключевого предложения:
Если вы используете якорь \G, вы вынуждаете матч после 22, чтобы начать с a. Регулярное выражение не может соответствовать, поскольку оно не найти цифру, поэтому следующее совпадение не удастся и оператор соответствия вернется пар, которые он уже нашел.
Это означает, что когда совпадение не выполняется, регулярное выражение не предпринимает дальнейших попыток и согласуется с примерами в ответах
Также:
После того, как совпадение завершится неудачей в письме a, perl сбрасывает pos() и следующий совпадение в одной строке начинается с начала.
Ответы
Ответ 1
\ G является якорем; он указывает, где матч должен быть запущен. Когда \G присутствует, он не может начать сопоставление в какой-либо произвольной более поздней точке строки; когда \G отсутствует, он может.
Это наиболее полезно при разборе строки в отдельные части, где вы не хотите пропускать другие вещи. Например:
my $string = " a 1 # ";
while () {
if ( $string =~ /\G\s+/gc ) {
print "whitespace\n";
}
elsif ( $string =~ /\G[0-9]+/gc ) {
print "integer\n";
}
elsif ( $string =~ /\G\w+/gc ) {
print "word\n";
}
else {
print "done\n";
last;
}
}
Вывод с \G's:
whitespace
word
whitespace
integer
whitespace
done
без
whitespace
whitespace
whitespace
whitespace
done
Обратите внимание, что я демонстрирую использование сопоставления scalar-context/g, но \G применяется в равной степени к сопоставлению контекста /g, и на самом деле вышеупомянутый код тривиально модифицируется для использования:
my $string = " a 1 # ";
my @matches = $string =~ /\G(?:(\s+)|([0-9]+)|(\w+))/g;
while ( my ($whitespace, $integer, $word) = splice @matches, 0, 3 ) {
if ( defined $whitespace ) {
print "whitespace\n";
}
elsif ( defined $integer ) {
print "integer\n";
}
elsif ( defined $word ) {
print "word\n";
}
}
Ответ 2
Но без \G совпадение будет пытаться в любом случае правильно?
Без \G
, это не будет связано с тем, чтобы начать сопоставление. Он попытается, но при необходимости попытается начать позже. Вы можете думать о каждом шаблоне как о предполагаемом \G.*?
спереди.
Добавьте \G
, и значение станет очевидным.
$_ = "1122a44";
my @pairs = m/\G (\d\d)/xg; # qw( 11 22 )
my @pairs = m/\G .*? (\d\d)/xg; # qw( 11 22 44 )
my @pairs = m/ (\d\d)/xg; # qw( 11 22 44 )
Честно говоря, из всего этого я не могу понять, в чем польза этого оператора и когда он должен применяться.
Как вы можете видеть, вы получаете разные результаты, добавляя \G
, поэтому полезность получает желаемый результат.
Ответ 3
Интересные ответы и многие действительны, я думаю, но я также могу предположить, что это все равно не объясняет много.
\ G 'заставляет "следующее совпадение встречаться в позиции, в которой закончилось последнее совпадение.
В принципе:
$str="1122a44";
while($str=~m/\G(\d\d)/g) {
#code
}
Первый матч = "11"
Второй матч FORCED TO START в 22 и да, это \d\d, поэтому результат равен "22"
Третья "попытка" FORCED начинается с "a", но это не \d\d, поэтому она терпит неудачу.