Я хочу регулярное выражение Perl, которое распознает дублированные слова в строке.
Учитывая следующий вход:
$str = "Thus joyful Troy Troy maintained the the watch of night..."
Я хотел бы следующий вывод:
Thus joyful [Troy Troy] maintained [the the] watch of night...
Это похоже на одно из упражнений 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, но это займет некоторое время, чтобы скомпилировать на моей крошечной машине.
Вы можете попробовать:
$str = "Thus joyful Troy Troy maintained the the watch of night...";
$str =~s{\b(\w+)\s+\1\b}{[$1 $1]}g;
print "$str"; # prints Thus joyful [Troy Troy] maintained [the the] watch of night...
Используемое регулярное выражение: \ b (\ w +) \ s + \ 1 \ b
Пояснение:
\ b
: word bondary \ w +
: слово ()
: запомнить указанное выше слово \ s +
: пробел \ 1
: запомненное слово Эффективно находит два полные слов, разделенных пробелом и помещающие вокруг них []
.
РЕДАКТИРОВАТЬ:
Если вы хотите сохранить количество пробелов между словами, которые вы можете использовать:
$str =~s{\b(\w+)(\s+)\1\b}{[$1$2$1]}g;