Чтобы сделать это как можно более простым, у вас есть ряд проблем, поэтому давайте сначала устраним очевидные.
Во-первых, вы не можете использовать символ косой черты ("/
") в строке, поскольку он имеет особое значение для per; например, «/n
» означает печать новой строки, а косая черта также используется для разделения части регулярного выражения. Когда вы хотите использовать косую черту в качестве литерала, решение состоит в том, чтобы избежать косой черты с обратной косой чертой, чтобы сказать Perl, что вы действительно хотите использовать косую черту, а не что-то особенное. Таким образом, ваш оригинальный код будет лучше написан так:
$a = "<no> 3232 <\/no> ";
$a =~ s/<no>(.*)<\/no>/000/gi;
Теперь Perl будет интерпретировать <\/no>
как </no>
Во-вторых, ваше регулярное выражение неверно. S /// regex указывает perl заменить / переформатировать шаблон в первом разделе на шаблон во втором разделе. Ваша инструкция в том виде, в каком она есть, говорит Perl, что нужно заменить все между первыми двумя слешами на «000» и присвоить ее переменной $ a.
Скобки, которые вы использовали в регулярном выражении, позволяют вам разбить выражение на куски smnaller и перестроить вещи, но вы их не использовали, однако вы на правильном пути. Чтобы повторно использовать части выражения в первом наборе слешей, которые вы хотите сохранить, вы заключаете их в квадратные скобки. Во второй части выражения вы можете ссылаться на эти «кусочки», используя $ 1, $ 2 и т. Д., Чтобы ссылаться на вещи в каждом наборе скобок.
Имея это в виду, у вас может возникнуть соблазн придумать что-нибудь вроде:
$a = "<no> 3232 <\/no> ";
$a =~ s/(<no>).*(<\/no>)/$1000$2/gi;
Это близко - как предложено выше - но тестирование покажет, что оно все еще не совсем верно; на этот раз вы получите еще более загадочный вывод </no>
. Это связано с тем, что perl интерпретирует строку как $ 1000, за которыми следуют $ 2, а $ 1000 ни к чему не относится. Если после $ 1 поставить пробел или еще что-то, это решит проблему. (Вероятно, есть какой-то способ более корректного завершения $ 1, но я признаюсь, что я этого не знаю.)
Следующее выражение будет работать, но вы получите пробел после первого, поэтому ваш выход будет <no> 000</no>
$a = "<no> 3232 <\/no> ";
$a =~ s/(<no>).*(<\/no>)/$1 000$2/gi;
Я бы предпочел использовать переменную вместо строки "000", и по этой причине мой код мог бы выглядеть примерно так:
$a = "<no> 3232 <\/no> ";
$b = "000";
$a =~ s/(<no>).*?(<\/no>)/$1$b$2/gi;
Использование переменной, на мой взгляд, делает вещи более понятными (хотя их можно было бы назвать лучше!), А также позволяет легко заменять текст («000») без необходимости связываться с регулярным выражением. ? в регулярном выражении подразумевает, что регулярное выражение не становится «жадным», если в строке более одного набора элементов - это приводит к тому, что. * останавливает сопоставление, как только встречает соответствующий шаблон, в этом случае "".