Он заменяет весь сопоставляемый шаблон, а не только то, что также фиксируется. Таким образом, вам нужно вернуть обратно Parens
$name =~ s/\(([0-9]+)\)/'('.($1 + 1).')'/e;
Поскольку заменяющая часть оценивается как код , это должен быть обычный код Perl, то есть кавычки и конкатенация, а также скобки для приоритета.
Чтобы добавить, есть шаблоны, которые не нужно возвращать в запасную часть: взгляды вперед и взгляд назад . Как и обычные якоря, это утверждения нулевой ширины , поэтому они не потребляют того, что им соответствует - вы только «смотрите»
$name =~ s/(?<=\() ([0-9]+) (?=\))/$1 + 1/xe;
Вид сзади не может быть переменной длины (например, \w+
); требуется только фиксированный строковый шаблон.
(?<=...)
утверждает, что шаблон (фиксированной длины) в скобках (которые не фиксируются!) Должен предшествовать числу, в то время как (?=...)
утверждает, что шаблон в его скобках должен следовать, чтобы весь шаблон совпадал.
Часто очень полезной является конструкция типа lookbehind \K
, которая заставляет двигатель сохранять в строке то, что он соответствовал до этого момента (вместо того, чтобы «потреблять» его); так что «отбрасывает» предыдущие матчи, очень похоже на (?<=...)
форму
$name =~ s/\(\K ([0-9]+) (?=\))/$1 + 1/xe;
Это также более эффективно. Хотя в документации это также называется «взглядом позади», на самом деле существуют различные различия в поведении. Смотрите этот пост и комментарии. Спасибо ikegami за комментарий.
Все это положительный внешний вид; Есть также отрицательные , утверждающие, что данные шаблоны не должны быть , чтобы все совпадало.
В этом случае немного излишне, но в некоторых других случаях это настоящий подарок.