Страница 1 из 2

Макросом не выцепить символ "/"

Добавлено: Пн июн 18, 2007 6:01 pm
4epT
На офе жалуются, что не выцепить никак символ "/", как только в шаблон впихиваешь этот символ (автомакрос вызываем условием "console /\//"), то кора ругается что-то типо:
OpenKore version 1.9.3
@ai_seq =
Loaded plugins:
plugins/alertsound.pl (alertsound)
plugins/doCommand.pl (doCommand)
plugins/macro.pl (macro)

Trailing \ in regex m/\/ at plugins/Macro/Utilities.pm line 116.
at plugins/Macro/Utilities.pm line 116

Macro::Utilities::match('Map loaded', '/\//') called at plugins/Macro/Automacro.pm line 343
Macro::Automacro::checkConsole('/\//', 'ARRAY(0x3389c58)') called at plugins/Macro/Automacro.pm line 435
Macro::Automacro::automacroCheck('log', 'ARRAY (0x3389c58)') called at plugins/Macro/Automacro.pm line 358
Macro::Automacro::consoleCheckWrapper('message', 'connection', 0, 1, 'Map loaded\x{a}', 'undef', 'main::parseSendMsg', 'main::mainLoop') called at H:/Game/Ragnarok/src/Log.pm line 252
Log::processMsg('message', 'Map loaded\x{a}', 'connection', 'undef', 1, 'HASH(0x11fd038)', 'HASH(0x11fd158)') called at H:/Game/Ragnarok/src/Log.pm line 274
Log::message('Map loaded\x{a}', 'connection') called at H:/Game/Ragnarok/src/functions.pl line 591
main::parseSendMsg('}\x{0}\x{89}\x{0}79d08d1\ x{e2}\x{ba}\x{db}\x{1}M\x{1}O\x{1}\x{0}\x{0}\x{0}\x{0}O\x{ 1}\x{0}\x{0}\x{0}\x{0}O\x{1}\x{1}\x{0}\x{0}\x{0}' ) called at H:/Game/Ragnarok/src/functions.pl line 231
main::mainLoop() called at H:/Game/Ragnarok/src/ Interface.pm line 79
Interface::mainLoop('Interface::Console::Win32=HASH (0x125d558)') called at openkore.pl line 359
main::__start() called at start.pl line 127


Died at this line:
if ($match == 0 && $text eq $kw) {return 1}
* if ($match == 1 && ($text =~ /$kw/ || ($flag eq 'i' && $text =~ /$kw/i))) {
no strict;
вот кусок файла plugins\macro\Utilities.pm:
sub match {
$cvs->debug("match (@_)", $logfac{function_call_auto});
my ($text, $kw) = @_;

unless (defined $text && defined $kw) {
error "match: wrong # of args\n", "macro";
return 0
}

my $match;
my $flag;

if ($kw =~ /^".*"$/) {$match = 0}
elsif ($kw =~ /^\/.*\/\w?$/) {$match = 1}
else {return 0}
($kw, $flag) = $kw =~ /^[\/"](.*?)[\/"](\w?)/;

if ($match == 0 && $text eq $kw) {return 1}
if ($match == 1 && ($text =~ /$kw/ || ($flag eq 'i' && $text =~ /$kw/i))) {
no strict;
foreach my $idx (1..$#-) {setVar(".lastMatch".$idx, ${$idx})}
use strict;
return 1
}

return 0
}
жирным выделена та самая 116 строка

а вот на счёт красного у меня и вопрос, вот это похоже шаблон, который обрабатывается в условиях автомакроса:
^[\/"](.*?)[\/"](\w?)
^ - начало строки
[\/"] - символ / или " (ну это понятно)
. - один произвольный символ
* - повторяется 0 или большее число раз
(.* - любое число любых символов)
? - повторяется 1 или 0 раз
(*? - станет 0 и более)

вот у меня такой вопрос (для тех кто знает regexp):
нафига в тут нужен символ "?", если и так получается любое число любых символов?

Интуитивно, я удалил его, получилось так: ^[\/"](.*)[\/"](\w?)
(Ну почти интуитивно, на самом деле у меня есть конструктор)

После этого всё прекрасно заработало.
Так вот вопрос не сильно ли этот "?" повлияет на работу всего плагина, дествительно ли он лишний?

Тема на офе обсуждается тут

ЗЫ: кстати точто также не выдирался знак ".

Добавлено: Пн июн 18, 2007 6:33 pm
piroJOKE
Парень, так просто опубликуй ЭТО - там!

Добавлено: Пн июн 18, 2007 6:43 pm
4epT
дык я думаю тут совет спросить, а потом там..
1. там модератор пишет что он не шарит в regexp
2. заипусь объяснять им чё я хочу :) (я нем изучал)
мне и так там пишут: "Wow 4epT you have terrible english."

Добавлено: Пн июн 18, 2007 7:19 pm
Jerry
я не знаю, как у вас в перле, а у нас в регекспах .*? это lazy, a .* это greedy.

Добавлено: Пн июн 18, 2007 8:01 pm
piroJOKE
4epT - насчет перевода на аглийский, оффтоп:
  • Тебе надо немного побаловаться с автоматическим переводчиком; причем английский даже не обязательно для этого знать.
    Метода такая (я ее уже описывал где-то): составляешь фразу, пытаясь избегать сленга, литературщины и идиом. Авто-переводчик тебе что-то выдает на английском. Берешь его английскую фразу, и засовуешь ее обратно в переводчик - получаешь ее на русском. Если ты из этого вторичного русского результата понимашь о чем идет речь - фразу на английском можно публиковать. Если нет - пытаешься перестроить конструкцию своей начальной фразы на русском так, чтобы она прошла этот... тест.
    NB: Чего не хавает переводчик: он пытается слово "пакет" представить как package, а нам нужно packet.

Добавлено: Пн июн 18, 2007 8:13 pm
4epT
что такое lazy и greedy? можно по подробнее

piroJOKE, задолбает так писать к ним :D
я пока голый текст с промта кидаю к ним, без перевода туда-сюда

кстати макрос
console /\// <<работает
а макрос:
console /[+-*/]/ <<выдаёт ошибку

видимо не выход я нашёл, или не универсальный

чуть позже:
видимо * не дружит с / когда они вместе
вот так всё работает: console /[*+-/]/

А вообще я нашёл выход, не удаляя знак вопроса из Utilities.pm

/ - можно вызвать, используя:
\x2F -шестнадцатеричную запись символа
вот так: console /\x2F/

Но вопрос для знающих людей остаётся открытым, нужен ли вопросик в Utilities.pm? (см. первый пост)

Кстати впрос №2:
Стоит ли теперь писать им про "ошибку", если решение найдено?

Добавлено: Пн июн 18, 2007 8:37 pm
Jerry
greedy матчит все, что найдет, а lazy - матчит минимум.
Пример: "This is a <EM>first</EM> test."
<.+> матчит "<EM>first</EM>"
<.+?> матчит "<EM>"

Добавлено: Пн июн 18, 2007 8:56 pm
4epT
Jerry, блин пока тебя понимал, чуть голову не сломал.. :D
Тут тогда получается тоже самое.
Пример: "console /\//"
если стоит так: [\/"](.*?)[\/"] - то мачит только символ \ (точнее должен мачить, а сам ошибку выдаёт)
а если: [\/"](.*)[\/"] - то мачит только символ \/ (как раз то что нада)

так? :wink:

Jerry, так что ты скажешь: это считается ошибкой (недоделкой) или символ / легче доставать из шестнадцатеричной записи символа (\x2F)?

и почему * не дружит с \
(так работает: [*+-/], а так нет: [+-*/])???

Добавлено: Пн июн 18, 2007 9:42 pm
Jerry
Кароче, [\/"](.*)[\/"] в строке "обезьянка "чуча"" матчит от всю строку от первого " до последнего ". А [\/"](.*?)[\/"] матчит "обезьянка "

и ээ типа я в этих перловых экранированиях не особо шарю. Но */ это скорее всего конец комментария. Попробуй написать ченть типа *\/

Добавлено: Вт июн 19, 2007 12:23 am
4epT
то что написал я уже понил

блин, ну дак чё ты скажешь по поводу:
это считается ошибкой (недоделкой) или символ / легче доставать из шестнадцатеричной записи символа (\x2F)?

Добавлено: Вт июн 19, 2007 12:57 am
Jerry
Что именно ошибка, я не понимаю чего тебе не нравится то? символ / надо экранировать символом \, это стандартный подход к спецсимволам. Чтобы ты мог написать \/\/ и это не воспринимулось как комментарий в виде //. Разберись тама с этими слешами, что у тебя с ними не так
\x2F кстати эквивалентно \/ (должно быть)

Добавлено: Вт июн 19, 2007 1:36 am
4epT
пля ты мну не понимаешь :( прочитай плиз первое сообщение, про экранирование я знаю (щас впадлу проверять заного, но когда я пробовал, то "*\/" не работало)

Добавлено: Вт июн 19, 2007 8:27 am
Jerry
в первом сообщении тока про "?"

Добавлено: Вт июн 19, 2007 1:14 pm
4epT
хм, попробую объяснить то, что я имею в виду:

Если плагин macros (думаю ты с ним знаком)
С помошью него можно выдирать regexp'ом выражения (с консоли, чата..)
Этот плагин выдирает по шаблону: [\/"](.*?)[\/"], т.е. "lazy-тип"
Возникла проблема выдрать символ /, например, когда ГМ спрашивает сколько будет 2/2. Если написать шаблон: /(\d+)([*+-/])(\d+)/, то макрос его рассматривает как /(\d+)([*+-/ - а это бред какой-то.

Отсюда 2 решения:

1. Так как такие проблемы возникают только с двумя (по логике вещей) символами (" и /), то можно в плагине оставить старый шаблон lazy-типа ([\/"](.*?)[\/"]) и использовать шестнадцатеричную запись символа. Для нашего примера получим:
/(\d+)([*+-\x2F])(\d+)/
Кстати, если символ / экранировать:
/(\d+)([*+-\/])(\d+)/
то всё равно шаблон видится как /(\d+)([*+-\/

2. Можно "расширить" шаблон плагина и сделать его greedy-типа ([\/"](.*)[\/"]), тогда наш шаблон из примера будет нормано работать:
/(\d+)([*+-/])(\d+)/

Вот и прошу совета бывалого, чё лучше (оптимальнее, логичне) первое или второе?

Добавлено: Вт июн 19, 2007 2:33 pm
Jerry
ээ чувак. А плагин sjn этим [\/"](.*?)[\/"] часом строку не проверяет на наличие символа / ? Ведь там наверно какой-нибудь грепоподобный синтаксис, типа /строка_регекспа/ и в строка_регекспа не должно быть символа /.