| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Perl: Общие вопросы > Парсинг без регулярных выражений |
| Автор: dimdiden 29.12.2014, 09:40 |
| Привет всем! Помогите с, на мой взгляд нестандартной задачей. Есть некий скаляр вида: 123adas433fdf545df5454 Вопрос как разбить эту строку на два массива: В первом первый элемент 123, второй 433, третий 545, т.е. только цифры. Во втором соответственно не цифры? Главное условие - не пользоваться регулярными выражениями и внешними модулями. Вот на такой стадии сейчас my $string = '123adas433fdf545df5454'; my @array = split '', $string; #загнал каждый символ в массив my @job = (); $job[0] = ''"; my @job1 = (); $job1[0] = ''"; #проинициализировал два массива для результатов и в них первый элемент my $i = 0; my $y = 0; # $i и $y - переменные для определения элементов массива foreach my $elem (@array) { # вот здесь и загвоздка. Цикл перебирает каждый элемент if (($elem ge 0)and($elem le 9)) { # массива array, если цифра - дописывает эту цифру к существующему $job[$i] = "$job[$i]$elem"; # элементу [0] массива job, если нет - дописывает к [0] элементу job1 } else { job1[$y] = "$job1[$y]$elem\n"; } } print "@job\n@job1"; Вопрос: как перескочить на следующий элемент массивов job и job1 для выполнения повторных действий? $i++ и $y++ не подходят, так как плюсуют от каждого прохода элементов в цикле. Заранее спасибо за помощь! |
| Автор: infarch 29.12.2014, 11:34 |
| А вас не смущает то, что критерий для разбиения в функции split это как раз регулярное выражение? То что вы там пишете пустую строку это уже детали. Получается что регулярка таки есть. Может вам смотреть в сторону unpack? |
| Автор: ginnie 29.12.2014, 13:00 | ||
dimdiden, вот мой вариант:
|
| Автор: dimdiden 30.12.2014, 17:28 | ||||
Если не против, задам вопросы, т.к. уровень очень слабый, прочитать до конца код не могу:
Здесь я так понимаю в хэше substrings инициализируются вложенные хэши number и string?
оператор or это ведь логическое "или". В этой строке идет инкрементация значения substrings{number}{length} или присваивание значению $substrings{number}{start} значения текущего $pos. Не могу прочитать эту строку. Здесь я так понимаю и происходит сохранение "кусочков" в необходимые по условию массивы. Объясни пожалуйста почему в цикле и за циклом присутствует эта строка кода. Поз. 18,22,26,27. Про sub пока что и задавать нечего, изучаю этот вопрос. Заранее сори что напрягаю! |
| Автор: ginnie 30.12.2014, 17:40 |
| В %substrings храним начальную позицию и длину числовой и символьной подстрок. В случае, если очередной символ оказался цифрой, надо инкрементировать счетчик цифр $substrings{number}{length}++, если текущее значение счетчика 0, значит мы работаем с новой подстрокой и надо сохранить начальную позицию $substrings{number}{start} = $pos. После начала новой подстроки нужно сохранить завершившуюся, для этого используется функция save_substring(). Она вызывается внутри цикла. Когда мы обработали все символы в строке цикл завершился, но одна из подстрок осталась не сохраненной (т.е. сохранение выполняется только при обнаружении новой подстроки). Поэтому после завершения цикла необходимо еще раз сохранить оставшиеся подстроки. P.S. по причине смены места работы был в трех местах на собеседовании (Яндекс, Mail.ru и Rambler) и должен признать, что уровень у меня тоже слабоват |
| Автор: dimdiden 2.1.2015, 15:09 |
| ginnie спасибо большое. Наконец я все понял, и даже про прототипы. Переделал код без них. Остался последний вопрос, что делает return в блоке функции? У брав его все работает и так. Подскажи пожалуйста! |
| Автор: ginnie 5.1.2015, 16:54 |
| dimdiden, return используется в функции для указания возвращаемого значения. Я его стараюсь всегда писать, чтобы сразу было видно, какое значение возвращается (если return не использовать, вернется последнее вычисленное в функции значение). В данном случае возвращаемое значение мне не нужно, поэтому использую return без значения. |
| Автор: gami 7.1.2015, 22:06 |
| Можно написать программку и попроще: use strict; my $string = '123adas433fdf545df5454'; my $m = -1; my ($p,$g); my (@strings, @numbers); for (my $pos = 0; $pos < length($string); $pos++) { my $char = substr($string,$pos,1); $g = $p; $p = (($char ge '0') && ($char le '9'))? \@numbers: \@strings; $m++ if $p != $g; $p->[$m / 2] .= $char; } print "@strings @numbers"; Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Parsing-bez-regulyarnykh-vyrazheny-id54a0f7bcae2015e21d8b4567#findElement_E7045_54ad83bfae201588138b485d_0 |
| Автор: dimdiden 13.1.2015, 16:21 | ||
Подскажите кто то где почитать про вот эти ходы. Вот в первом выражении что означает знак вопроса и двоеточие после ссылки на numbers? Во второй строчке вообще ничего не пойму. Буду признателен за помощь. Добавлено через 4 минуты и 20 секунд
Стоять! Вышел на термин "тернарный оператор", сейчас покурю эту тему. Остальное под вопросом) |
| Автор: ginnie 13.1.2015, 16:46 | ||
dimdiden, $m - уменьшенный на 1 счетчик групп символов, $m/2 - индекс текущей группы в массивах (берется целая часть от деления на 2).
добавляет в конец текущей группы символ $char. |
| Автор: dimdiden 13.1.2015, 17:04 |
| Спасибо большое! |