-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBackreferences.pm
More file actions
60 lines (55 loc) · 2.28 KB
/
Backreferences.pm
File metadata and controls
60 lines (55 loc) · 2.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package RegexStuff;
use strict;
use warnings;
use overload;
sub import { overload::constant('qr' => \&MungeRegexLiteral) }
my $NestedStuffRegex; # Переменная используется в собственном
# определении. Поэтому она должна определяться заранее.
$NestedStuffRegex = qr{
(?>
(?: # Не круглые скобки, не '#' и не '\' ...
[^()\#\\]+
# Экранирование...
| (?s: \\. )
# Комментарии в регулярном выражении...
| \#.*\n
# Круглые скобки, внутри которых могут находиться
# другие вложенные конструкции...
| \( (??{ $NestedStuffRegex }) \)
)*
)
}x;
sub SimpleConvert; # Функция вызывается рекурсивно, поэтому
# ее необходимо объявить заранее
sub SimpleConvert
{
my $re = shift; # Регулярное выражение для обработки
$re =~ s{
\(\? # "(?"
< ( (?>\w+) ) > # <$1 > $1-идентификатор
($NestedStuffRegex) # $2-вложенные конструкции
\) # ")"
}{
my $id = $1;
my $guts = SimpleConvert($2);
"(?:($guts)(?{ local(\$^T{'$id'}) = \$^N }))"
}xeog;
return $re; # Вернуть обработанное регулярное выражение
}
sub MungeRegexLiteral
{
my ($RegexLiteral) = @_; # Аргумент-строка
print "BEFORE: $RegexLiteral\n"; # Снять комментарий при отладке
my $new = SimpleConvert($RegexLiteral);
if ($new ne $RegexLiteral)
{
my $before = q/(?{ local(%^T) = () })/; # Локализация
# временного хеша
my $after = q/(?{ %^N = %^T })/; # Копирование временного
# хеша в "настоящий"
$RegexLiteral = "$before(?:$new)$after";
}
print "AFTER: $RegexLiteral\n"; # Снять комментарий при отладке
return $RegexLiteral;
}
1;