"нетерпеливое" соответствие регулярному выражению

Мне нужно удалить строку между двумя разделителями, т.е. Из "123XabcX321" я хочу "123321". Для простого случая, я в порядке:

$_=<>;
s/X(.*)X//;
print;

Но если есть двусмысленность во вводе типа "123XabcXasdfjXasdX321", он соответствует первому X с последним X, и я получаю "123321", но я хочу "123asdfj321". Есть ли способ указать "нетерпеливое" соответствие, совпадающее с первым допустимым возможным разделителем, а не последним?

Ответ 1

Обычно называется "негритяным", вы ставите? после квантификатора: s/X(.*?)X//;

Ответ 2

Избегайте не-жадного модификатора как ничего, кроме подсказки производительности, если сможете. Использование этого метода может привести к "неожиданным" результатам, поскольку добавление ? фактически не препятствует .* сопоставить что-либо. Например,

$ perl -le'print for "XaXbXY" =~ /X(.*?)XY/;'
aXb

Чтобы избежать соответствия X, вы можете использовать следующее:

s/X[^X]*X//g;

Если X действительно больше чем один символ, вы можете использовать следующее:

s/X(?:(?!X).)*X//g;