|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июн 21, 2004 01:36:06 · Поправил: Asterix Лень искать - решил спросить ;-) Вопрос касательно Perl'а. Допустим имею я в программе переменные $temp1='cdcdcdc'; $temp2='bcbcbcbcb'; $temp3='asasasa'; как бы мне организовать обход этих переменных в цикле, если допустим требуется выполнить s/$temp//g; # где $temp последовательно должна принимать значения $temp1, $temp2, $temp3 |
|
|
Дата: Июн 21, 2004 05:45:40 Видимо никто из неспящих не знает ;-) Сам я сделал через список так: @temp=("cdcdcdc","bcbcbcbcb","asasasa");
$i=0;
while ($i<=2)
{
s/$temp[$i]//g;
$i++;
} |
|
|
Дата: Июн 21, 2004 06:29:44 Туплю, так будет правильнее: @temp=("cdcdcdc","bcbcbcbcb","asasasa");
foreach $i (@temp)
{
s/$i//g;
} |
|
|
Дата: Июн 21, 2004 18:11:00 Лишь два совета, о великий :) 1) Используй $_, т.к. в этом случае производительность будет выше - перлу не надо будет создавать память для $i. 2) Используй не \"\" в качестве кавычек, а \'\', т.к. в этом случае перл не будет производить ресолвинг строк внутри кавычек, что также поднимет производительность :) Т.е. переписанный с учетом оптимизации клочок выглядит так:
foreach ('cdcdcdc','bcbcbcbcb','asasasa')
{
s/$_//g;
}
|
|
|
Дата: Июн 21, 2004 21:53:46 volodya Действительно, я не в восторге от скорости :-( Вопрос такой, можно ли использовать неявную переменную $_ если код у меня такой(естес-но это кусок): @BYTE=('BYTE','CHAR','BOOLEAN');
while(<IN>)
{
foreach $i (@BYTE)
{
s/^(\s*)$i\s+([a-zA-Z0-9_]+)\s*;(.*)/$1.$2 db ?$3/g;
s/^(\s*)$i\s+([a-zA-Z0-9_]+)\[([0-9]+)\]\s*;(.*)/$1.$2 rb $3$4/g;
s/^(\s*)$i\s+([a-zA-Z0-9_]+)\[([\sA-Z0-9_\+\-\*]+)\]\s*;(.*)/$1.$2 rb $3$4/g;
}
print OUT $_;
} |
|
|
Дата: Июн 21, 2004 23:06:31 И опять эта твоя стратегия с заменой... Сами по себе эти регулярки очень медленны. А если ты еще хочешь и s, да еще и со спецификатором g, то чего же ты ждешь? Медленно это будет и все. Теперь сугубо по твоему вопросу. Точный ответ: я не знаю :) Более расплывчато: у каждой переменной есть своя область видимости (scope по-английски). Так вот, внутри WHILE при foreach у тебя есть scope, и, возможно, $_ в скопе внутри foreach будет одна, а при выходе из foreach будет восстановлена старая $_. Однако это надо проверить. Просто-напросто вставь print в foreach и print в while и погляди, что там к чему :) |
|
|
Дата: Июн 21, 2004 23:07:44 тогда лучше не читай строку в $_ сделай так: while ($string = <IN>) foreach (@BYTE) { s/^(\s*)$_\s+([...... ........ } print OUT $string; хотя не вижу всего алгоритма, думаю, что $string как раз у тебя и разбивается в @BYTE и не уверен, что это все будет намного быстрее (если вообще будет) |
|
|
Дата: Июн 21, 2004 23:12:44 Да, и еще. Опять вопрос стиля, но можно пожертвовать в пользу производительности. Ты пишешь, @BYTE=('BYTE','CHAR','BOOLEAN'); Это неплохо, но перл вынужден создать внутреннюю переменную под массив (тип AV, если тебе любопытно: http://gisle.aas.no/perl/illguts/) и скопировать туда данные. Этого можно избежать, просто написав сие: foreach ('BYTE','CHAR','BOOLEAN')
{
#do what you need to do
}
В этом случае программа становится менее понятной, но более быстрой. Чему отдать предпочтение - дело за тобой. |
|
|
Дата: Июн 21, 2004 23:14:09 Mad_C Вот это: while ($string = <IN>) хуже, чем это: while(<IN>) Asterix сделал все верно. Твой вариант еще медленнее. |
|
|
Дата: Июн 21, 2004 23:16:31 а ты уже выяснил область видимости $_ ??? |
|
|
Дата: Июн 21, 2004 23:20:52 · Поправил: volodya Уже да :)
open (IN, 'foo.txt');
while(<IN>)
{
foreach('BYTE','CHAR','BOOLEAN')
{
print;
}
print;
}
close(IN);
Работает как и предполагалось. $_ восстанавливается по выходу из цикла foreach, что хорошо :) |
|
|
Дата: Июн 21, 2004 23:22:21 тогда сорри, несомненно так лучше :))) |
|
|
Дата: Июн 22, 2004 00:53:50 volodya Нет, нифига не получилось :-( Скрипт в таком виде(ниже) перестал работать, а я хотел сделать цикл не только для BYTE но и для WORD/DWORD и т.д. #!/usr/bin/perl -w
print("Processing, please wait.\n");
foreach $f (<*.h>)
{
open(IN, "$f") or die "Can't open file: $!";
chop($f);
chop($f);
open(OUT, "+>$f\_.inc") or die "Can't open file out.inc for writing: $!";
while(<IN>)
{
# конвертирование заголовков структур
s/\btypedef\s+(struc)t(\s+)_([a-zA-Z0-9_]+)(.*)/$1$2$3$4/ig;
s/\btypedef\s+(struc)t(\s+)tag([a-zA-Z0-9_]+)(.*)/$1$2$3$4/ig;
s/\btypedef\s+(struc)t(\s+)([a-zA-Z0-9_]+)(.*)/$1$2$3$4/ig;
# конвертирование параметров структур
# 8 bit BYTE
foreach('BYTE','CHAR','BOOLEAN')
{
s/^(\s*)$_\s+([a-zA-Z0-9_]+)\s*;(.*)/$1.$2 db ?$3/g;
s/^(\s*)$_\s+([a-zA-Z0-9_]+)\[([0-9]+)\]\s*;(.*)/$1.$2 rb $3$4/g;
s/^(\s*)$_\s+([a-zA-Z0-9_]+)\[([\sA-Z0-9_\+\-\*]+)\]\s*;(.*)/$1.$2 rb $3$4/g;
}
# 16 bit WORD
s/\bWORD\s+([a-zA-Z0-9_]+)\s*;(.*)/.$1 dw ?$2/ig;
s/\bDWORD\s+([a-zA-Z0-9_]+)\s*;(.*)/.$1 dd ?$2/ig;
s/\bLONG\s+([a-zA-Z0-9_]+)\s*;(.*)/.$1 dd ?$2/ig;
s/\bWORD\s+([a-zA-Z0-9_]+)\[([0-9]+)\]\s*;(.*)/.$1 rw $2$3/ig;
s/\bDWORD\s+([a-zA-Z0-9_]+)\[([0-9]+)\]\s*;(.*)/.$1 rd $2$3/ig;
s/\bWORD\s+([a-zA-Z0-9_]+)\[([\sA-Z0-9_\+\-\*]+)\]\s*;(.*)/.$1 rw $2$3/ig;
s/\bDWORD\s+([a-zA-Z0-9_]+)\[([\sA-Z0-9_\+\-\*]+)\]\s*;(.*)/.$1 rd $2$3/ig;
# конвертирование констант
# десятичных
s/^#define\s+([a-zA-Z0-9_]+)(\s+)([0-9]+\b)(.*)/$1$2= $3$4/ig;
s/^#define\s+([a-zA-Z0-9_]+)(\s+)\(\s*([0-9]+)\s*\)(.*)/$1$2= $3$4/ig;
# шестнадцатиричных
s/^#define\s+([a-zA-Z0-9_]+)(\s+)0x([a-fA-F0-9]+\b)(.*)/$1$2= $3h$4/ig;
s/^#define\s+([a-zA-Z0-9_]+)(\s+)\(\s*0x([a-fA-F0-9]+)\s*\)(.*)/$1$2= $3h$4/ig;
s/^#define\s+([a-zA-Z0-9_]+)(\s+)\(\s*0x([a-fA-F0-9]+)L\s*\)(.*)/$1$2= $3h$4/ig;
s/^#define\s+([a-zA-Z0-9_]+)(\s+)\(\s*\(\s*DWORD\s*\)\s*0x([a-fA-F0-9] +)\s*\)(.*)/$1$2= $3h$4/ig;
s/^#define\s+([a-zA-Z0-9_]+)(\s+)\(\s*\(\s*DWORD\s*\)\s*0x([a-fA-F0-9] +)L\s*\)(.*)/$1$2= $3h$4/ig;
# конвертирование комментариев, т.е. '//' заменяем на ';'
s/\/\//;/g;
print OUT $_;
}
close(OUT);
close(IN);
} |
|
|
Дата: Июн 22, 2004 01:00:06 > И опять эта твоя стратегия с заменой... По другому никак, только регулярки, причём эти у меня ещё не совсем правильны, возможны ложные срабатывания, но постепенно привожу их к нужному виду. |
|
|
Дата: Июн 22, 2004 01:02:29 По другому никак Это тебе так только кажется :) Скрипт в таком виде(ниже) перестал работать Что значит, перестал работать? Хочешь, чтобы я тебе тестером работал? :) Если да - то давай мне входной файл, посмотрю. Да, как там моя просьба поживает, а? |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.044 |