Это похоже на одно из Learning Perl упражнений. Хитрость заключается в том, чтобы перехватить все повторяющиеся слова, поэтому вам необходим квантификатор «один или несколько» при дублировании:
$str = 'This is Goethe the the the their sentence';
$str =~ s/\b((\w+)(?:\s+\2\b)+)/[\1]/g;
Функции, которые я собираюсь использовать, описаны либо в perlre , когда они применяются к шаблону, либо в perlop , когда они влияют на работу оператора подстановки.
Если вам нравится флаг /x
для добавления незначительных пробелов и комментариев:
$str =~ s/
\b
(
(\w+)
(?:
\s+
\2
\b
)+
)
/[\1]/xg;
Мне это не нравится \2
, хотя, потому что я ненавижу считать относительные позиции. Я могу использовать относительные обратные ссылки в Perl 5.10. \g{-1}
относится к непосредственно предшествующей группе захвата:
use 5.010;
$str =~ s/
\b
(
(\w+)
(?:
\s+
\g{-1}
\b
)+
)
/[\1]/xg;
Счет не так уж и велик, поэтому я могу использовать помеченные спички:
use 5.010;
$str =~ s/
\b
(
(?<word>\w+)
(?:
\s+
\k<word>
\b
)+
)
/[\1]/xg;
Я могу пометить первый захват ($1
) и получить доступ к его значению через %+
позже:
use 5.010;
$str =~ s/
\b
(?<dups>
(?<word>\w+)
(?:
\s+
\k<word>
\b
)+
)
/[$+{dups}]/xg;
Мне действительно не нужен этот первый снимок, потому что он просто для того, чтобы ссылаться на все, что соответствует. К сожалению, похоже, что ${^MATCH}
не установлено достаточно рано, чтобы я мог использовать его на стороне замены. Я думаю, что это ошибка. Это должно работать, но не работает:
$str =~ s/
\b
(?<word>\w+)
(?:
\s+
\k<word>
\b
)+
/[${^MATCH}]/pgx; # DOESN'T WORK
Я проверяю это на blead, но это займет немного времени, чтобы скомпилировать на моей крошечной машине.