Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Как заэкранировать все символы в переменной


Автор: Suppir 15.3.2011, 09:15
В регулярном выражении использую переменную:

if (/$exceptions/){}

где $exceptions = "исключение1|исключение2|исключение3|..."

Исключения представляют собой обычные строки вида:

"Расчет максимального среднего дневного заработка для исчисления пособий по временной нетрудоспособности"
"Независимо от места прохождения военной службы по контракту (на территории России или за ее пределами)"
"Размер единовременного пособия при рождении ребенка проиндексирован в соответствии со статьей 4.2"

Каким образом можно заэкранировать все символы в исключениях, которые могут интерпретироваться как метасимволы в регулярном выражении? 
Например, во втором исключении есть скобки, необходимо перед каждой скобкой поставить \(. 
Также могут встречать другие метасимволы:  [] ?, +, . , >, < и т.д. 
Существует ли надежный способ экранирования?


Автор: arto 15.3.2011, 09:47
perldoc perlre на предмет Escape sequences

Автор: Suppir 15.3.2011, 10:01
В общем, готового решения нет?


Еще один момент. У меня следующее регулярное выражение:


Код

    $doc =~ s/
            (^-{66}\n)
                (?:     
                    (?:^
                        (?!
                            (?:
                                [\d¦(]
                                |[а-яa-b]\)
                                |[^"]{1,13}[XХVI\d]\.\h
                                |.+\h\(далее\h?-
                                |можно ли в этом месте перебрать все ключи из хеша или массива?
                            )
                        ).{20,}\n
                        |^\n
                    )+\1
                )+
                (?{$c++; print COM "$&\n"})
            //mgx;

Автор: arto 15.3.2011, 10:41
смотря что понимать под "готовым решением".

непонятен глагол "перебрать"

Автор: sir_nuf_nuf 15.3.2011, 11:33
есть варианты:
Код

my $var = 'a*b+';
my $re1 = qr/\Q$var\E/;   - не безопасно.. в $var может быть \E
my $var2 = quotemeta($var);
my $re2 = qr/$var2/; - это по идее лучше

Автор: arto 15.3.2011, 11:51
не влияет:
# print -l "aa" "bb" "cc" "dd" | perl -lne '$a = "aa|bb\\E|cc"; print "$_: ",(m#$a# ? "yes" : "no")'
aa: yes
bb: no
cc: yes
dd: no
# print -l "aa" "bb" "cc" "dd" | perl -lne '$a = "aa|bb\\E|cc"; print "$_: ",(m#\Q$a\E# ? "yes" : "no")'
aa: no
bb: no
cc: no
dd: no
# print -l "aa" "bb" "cc" "dd" | perl -lne '$a = "aa|bb\\E|cc"; print "$_: ",(m#\Q$a\E|dd# ? "yes" : "no")'
aa: no
bb: no
cc: no
dd: yes

Автор: Suppir 15.3.2011, 12:48
Цитата(arto @  15.3.2011,  10:41 Найти цитируемый пост)
непонятен глагол "перебрать" 


допустим, есть хеш с ключами вида

исключение1
исключение2
исключение3


я хочу вставить эти исключения в регулярное выражение 
Код

 $doc =~ s/
            (^-{66}\n)
                (?:     
                    (?:^
                        (?!
                            (?:
                                [\d¦(]
                                |[а-яa-b]\)
                                |[^"]{1,13}[XХVI\d]\.\h
                                |.+\h\(далее\h?-
                                |исключение1
                                |исключение2
                                |исключение3
                            )
                        ).{20,}\n
                        |^\n
                    )+\1
                )+
                (?{$c++; print COM "$&\n"})
            //mgx;





Если исключений мало, то можно просто склеить все строки в одну переменную: $var = "исключение1|исключение2|исключение3". Но если этих исключений больше сотни, то скорость регулярного выражения сильно упадет. Существует ли возможность проверки из регулярного выражения на наличие совпавшего куска в хеше?
Например, мы захватили фрагмент в переменную (.+), а теперь нужно сделать проверку вроде if (exists $exceptions{$1}){do_smth()}

Автор: arto 15.3.2011, 13:04
perldoc perlre на предмет "(??{ code })", может поможет

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)