С некоторыми предупреждениями один может сделать это, используя расширенный шаблон (??{ code })
use warnings;
use strict;
use feature 'say';
sub form_patt { return '[0-9]+' }
my $re = qr/ [a-z] (??{ form_patt() }) /x;
#say $re;
my $v = q(z23 b71);
my @m = $v =~ /($re)/g;
say "@m";
Конструкция позволяет любому коду Perl выполняться внутри шаблон, и возвращаемое значение этого кода
обрабатывается как шаблон, компилируется, если это строка (или используется как есть, если это qr//
объект), а затем сопоставляется, как если бы он были вставлены вместо этой конструкции.
Таким образом, мы можем сгенерировать (под) шаблон, запустив код внутри самого регулярного выражения (не обязательно в qr
).
Недостатком является то, что его вполне можно оценивать каждый раз, когда его используют (даже если в переменной с qr
объектом). Кроме того, это сложная особенность; пожалуйста, смотрите документацию.
Это регулярное выражение нуждается в корректировках, как обсуждалось; по крайней мере, чтобы экранировать ASCII не-словесных символов с quotemeta . Скорее всего, шаблоны также должны быть привязаны (привязаны).
Если ключи входят в более длинную строку (более широкое требование, чем в ответе на ysth), то привязайте шаблон к границе слова \b
, чтобы искать key
не соответствует keys
'\b(?:' . join('|', map { quotemeta } keys %hash) . ')\b'
Это одна возможность, в зависимости от точных требований, которые не были даны.