Запутался в Perl, подскажите.

Romka_Kharkov
На сайте с 08.04.2009
Offline
485
766

День добрый,


#!/usr/bin/perl

$a = "ad!qqq!ad";
$b = "q.q";

if ($a =~ /(.+)!$b!(.+)/) { print "ok\n"; }

Выдает "ok". Т.е на сколько я понимаю точка в переменной $b трактуется как любой символ или что-то в этом роде, каким образом провести аналогичное сравнение только что бы точка воспринималась как точка, при этом сравнение происходить должно по шаблону /(.+)!$b!(.+)/

Я не супер программист на perl но надо решить этот ребус как-то...

На самом деле оригинальная конструкция выглядит так:


while(<S>) {
if ($_ =~ /(.+)!$username!(.+)/) {

Т.е циклом из файла читаются строки и если совпадает $username происходит действие, однако начинают совпадать имена типа "vasya" и "v.sya", а оба являются реальными, надо что бы они различались...

Если делать просто if ($a eq $b) { ... } то все нормально , но как "eq" прикрутить к шаблону /(.+)!$b|(.+)/ не пойму :(

Заранее спасибо.

Есть около 15.000 ipv4 !!! (http://onyx.net.ua/price.php#ipv4) Качественный хостинг с 2005 года - лучшее клиентам! (http://onyx.net.ua/)
iHead
На сайте с 25.04.2008
Offline
137
#1

попробуй обрамить переменную \Q и \E:


if ($a =~ /(.+)!\Q$b\E!(.+)/) { print "ok\n"; }
Рекомендуемый хостинг партнер 1С-Битрикс (https://www.ihead.ru/bitrix/), PHP-хостинг (https://www.ihead.ru/php/), доверенный партнер RU-CENTER (https://www.ihead.ru/news/573.html), официальный представитель REG.RU в Кирове (https://www.ihead.ru/news/851.html)
Romka_Kharkov
На сайте с 08.04.2009
Offline
485
#2

iHead, вроде бы стработало, где почитать что дает \Q \E ?

Andreyka
На сайте с 19.02.2005
Offline
822
#3
Не стоит плодить сущности без необходимости
iHead
На сайте с 25.04.2008
Offline
137
#4
Romka_Kharkov:
iHead, вроде бы стработало, где почитать что дает \Q \E ?

это эквивалент quotemeta

bbon
На сайте с 01.04.2006
Offline
127
#5
Romka_Kharkov:
Выдает "ok". Т.е на сколько я понимаю точка в переменной $b трактуется как любой символ или что-то в этом роде

Да, как любой символ. В вашем примере достаточно было вместо

$b = "q.q";

написать

$b = 'q\.q';
(одинарные кавычки обязательны)
Romka_Kharkov
На сайте с 08.04.2009
Offline
485
#6

bbon, Спасибо, но не совсем так, я написал выше, что оригинальное сравнение происходит по файлу который читается:


while(<S>) {
if ($_ =~ /(.+)!$username!(.+)/) {

По этому $username изначально не известен.... он приходит в переменную, по этому как туда применить экранирование - не ясно :(

А данную конструкцию я просто привел для примера, что бы проверить....

Представьте что перед while() например стоит $username = $ARGV[0];

bbon
На сайте с 01.04.2006
Offline
127
#7
Romka_Kharkov:
bbon, Спасибо, но не совсем так, я написал выше, что оригинальное сравнение происходит по файлу который читается:


while(<S>) {
if ($_ =~ /(.+)!$username!(.+)/) {


По этому $username изначально не известен.... он приходит в переменную, по этому как туда применить экранирование - не ясно :(

А данную конструкцию я просто привел для примера, что бы проверить....

Представьте что перед while() например стоит $username = $ARGV[0];

Ну, тогда, самое простое, как вам написали выше - использовать \Q (запрет на метасимволы), я не знаю всей задачи, но мне кажется, что (.+) - лишнее, иначе не отловит имя пользователя в начале-конце строки, примерно так

my $username = $ARGV[0];


while(<S>) {
if (m/!(\Q$username\E)!/i) { # i - регистр не важен
print $1, " - ok\n"; # $1 - найденное в скобках совпадение
}
else {
print "not ok\n";
}
}
Romka_Kharkov
На сайте с 08.04.2009
Offline
485
#8
bbon:
я не знаю всей задачи, но мне кажется, что (.+) - лишнее, иначе не отловит имя пользователя в начале-конце строки, примерно так

Совершенно верно, его там быть и не должно (имя пользователя в начале строки) файл подается в строгом формате xxx!$username!xxx это уже вторичная обработка данных так сказать, сначала создается тот самый файл... Ну в общем это уже не важно, всем спасибо за пояснения и участие!!!

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий