quotemeta
- это хорошая функция для получения точного литерала со специальными символами в регулярном выражении. И \Q
и \E
являются хорошими операторами для того же действия внутри регулярного выражения.
Однако, ваше поисковое выражение не так уж сложно. При редактировании вы просто ищете двойную кавычку и косую черту. На самом деле, я довольно упростил ваше выражение, так что оно не содержит ни одной обратной косой черты . Так что это не проблема для quotemeta
, и в этом отношении \Q
и \E
.
После сокращения я не вижу в вашей исправленной замене ничего, что могло бы вызвать проблему с '?' в $tline
.
Ключом к упрощению является то, что '.', '(' И ')' ничего не значат для секции replace вашего выражения, так что это эквивалентно:
$tline =~ s/"\//"<%=request.getContextPath()%>\//;
Не говоря уже о том, что его легче читать. Конечно, это еще проще:
$tline =~ s|"/|"<%=request.getContextPath()%>/|;
Поскольку в Perl вы можете выбрать желаемый разделитель с помощью оператора s
.
Но с любым из них это работает:
use Test::More tests => 1;
my $tline = '"/?"';
$tline =~ s|"/|"<%=request.getContextPath()%>/|;
ok( $tline =~ /getContextPath/ );
Проходит тест. Возможно, у вас проблема с более чем одной заменой в строке. Это можно исправить с помощью:
$tline =~ s|"/|"<%=request.getContextPath()%>/|g;
То, что g является переключателем global на конце, говоря, производите эту замену столько раз, сколько это происходит на входе.
Однако, поскольку я могу видеть, что вы делаете, я предлагаю еще более точное определение того, что вы хотите найти:
$tline =~ s~\b(href|link|src)="/~$1="<%=2request.getContextPath()%>/~g;
И когда я запускаю это:
use Test::More tests => 2;
my $tline = '"/?"';
$tline =~ s/"\//"<%=request.getContextPath()%>\//;
ok( $tline =~ /getContextPath/ );
$tline = 'src="/?/?/beer"';
ok( $tline =~ s~\b(href|link|src)="/~$1="<%=request.getContextPath()%>/~g
);
У меня два успеха.
Ваша true проблема еще не определена.