Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Поиск подстроки в строке 
V
    Опции темы
MZ412
Дата 22.1.2010, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Приветствую.
Решаю маленькую задачу по парсингу текста.
Есть код:

Код

$str = "bla1, bla2, '13843', bla3"; #исходная строка
$pos1 = index ($str, "'", 0);
$pos2 = rindex ($str, "'");

$substr = substr ($str, $pos1 + 1, $pos2 - $pos1 - 1);
print "$substr\n";


Скажем так, я гарантировано знаю, что подстрока будет ограничена символом '
Всё, что я нагуглил и начитал в учебнике говорит мне о том, что для извлечения подстроки из строки надо использовать функции index и rindex.
Но есть у меня подозрение, что это решение не изящно. Не подскажете, в какую сторону копать?

Наверняка же можно записать всё в виде
Код

$substr = $str =~ m/^.+'[0-9]'.+$/;

и вытащить из какой-нибудь системной переменной...

Это сообщение отредактировал(а) MZ412 - 22.1.2010, 12:04
PM MAIL   Вверх
arto
Дата 22.1.2010, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



можно.
у вас задача какая?
PM MAIL ICQ   Вверх
mastercz
Дата 22.1.2010, 12:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет



может като так ?
@substr = $str =~ m/\'.*?\'/g;
PM MAIL   Вверх
sir_nuf_nuf
Дата 22.1.2010, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 920
Регистрация: 6.1.2008

Репутация: 14
Всего: 31



Код

my ($substr) = $str =~ m/^.+'([0-9])'.+$/;

или
Код

$str =~ m/^.+'([0-9])'.+$/;
$substr = $1;

или

ну вы поняли.. 


--------------------
user posted image
user posted image
PM MAIL Jabber   Вверх
MZ412
Дата 22.1.2010, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Всех благодарю. Прицип понял. )
PM MAIL   Вверх
ginnie
Дата 22.1.2010, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



sir_nuf_nuf, может правильнее так:
Код

my ($substr) = $str =~ m/^.+'([0-9]+)'.+$/;




--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
MZ412
Дата 22.1.2010, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Если немного развить тему...

Суть самой задачи - извлечение из весьма кривого лога (нет возможности переписать) хэш массива с данными.
Сам лог выглядит так:

Код

$stat = [
          965286138,
          965286138,
          '168787.951737965',
          0,
          1264154697
        ];


Да, именно так, с переводами строки. Т.е. каждая "строка" лога - вот такое вот безобразие.

Собственно требуется наполнить хэш массив вида
Код

%input = (
        speed => "";
        data  => "";
)

speed - это значение в одинарных кавычках.
data - это последняя цифра (время в unix формате), в данном примере - 1264154697.

Я правильно вижу ситуацию, что самый простой вариант - считать в скаляр такой вот блок информации, удалить все переводы строки и работать, как с простой строкой, изврекая regexp-ом нужные фрагменты и записывая их в хэш массив?

PM MAIL   Вверх
ginnie
Дата 22.1.2010, 13:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



MZ412, если набор данных в исходном файле постоянный, зачем сначала их объединять, а затем выбирать из них нужные при помощи рег. выражений? Почему нельзя сразу считать нужные значения?


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
mastercz
Дата 22.1.2010, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 112
Регистрация: 5.11.2008

Репутация: нет
Всего: нет





Код

%input = ();
@sort_key=('speed','data');
$i=0;

foreach  my $var (@{$stat}) 
 {
    $input{$sort_key[$i]}=$var;
  $i++
 } 

PM MAIL   Вверх
arto
Дата 22.1.2010, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1495
Регистрация: 31.10.2004

Репутация: 38
Всего: 40



perl -073 -lne 'eval $_ && push @ary,{ speed => $stat->[2], data => $stat->[4] }'
PM MAIL ICQ   Вверх
MZ412
Дата 22.1.2010, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



2ginnie
Цитата

MZ412, если набор данных в исходном файле постоянный, зачем сначала их объединять, а затем выбирать из них нужные при помощи рег. выражений? Почему нельзя сразу считать нужные значения?


Правильно ли я понял идею?
Считываю построчно файл. Учитывая то, что оба значения, которые меня интересуют, чередуются в определённом порядке, то я просто сверяю с regexp-ами для каждого поочерёдно каждую строку, и, в случае попадания пишу данные в хэш?

2mastercz
Цитата

%input = ();
@sort_key=('speed','data');
$i=0;

foreach  my $var (@{$stat}) 
 {
    $input{$sort_key[$i]}=$var;
  $i++
 } 


Силюсь понять, честно. Но что находиться в переменной $stat ? Считанная строка?

2arto
Выполнять в shell-e мне не хотелось бы, т.к. буду потом эти данные в RRD бызу загонять и графики строить.

Это сообщение отредактировал(а) MZ412 - 22.1.2010, 14:05
PM MAIL   Вверх
ginnie
Дата 22.1.2010, 14:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



MZ412, поняли правильно. Я бы сверял только '$stat = [', чтобы контролировать, что файл единообразный. Регулярные выражения я бы использовал для удаления переноса строк и запятых с кавычками.


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
MZ412
Дата 22.1.2010, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



В общем - рашил это так:

Код

#!/usr/bin/perl -w

use strict;
use warnings;

my $substr;
my %input = ();
my $i = 0;
my $c = 0;

while (<STDIN>)
{
        #ищем вхождение, соответствующее скорости
        if (($substr) = $_ =~ m/^.+'(([0-9]|.)+)'.+$/)
        {
                if ($substr)
                {
                        $input{'speed'}{$i} = $substr;
                }
        }
        #скорость иногда отсутствует, по этому проверяем, чтобы не было пустого ключа
        if ($input{'speed'}{$i})
        {
                #ищем вхождение, соответствующее дате
                if (($substr) = $_ =~ m/^\s+([0-9]+)\s+$/)
                {
                        $input{'data'}{$i} = $substr;
                        #при полной паре записей обновляем индекс
                        $i++;
                }
        }
}

#для отладки...
for($c = 0; $c < $i; $c++)
{
        print "data: $input{'data'}{$c}\n";
        print "speed: $input{'speed'}{$c}\n";
}

PM MAIL   Вверх
ginnie
Дата 22.1.2010, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



MZ412, и что, это у Вас правильно работает?

Кстати, вместо m/^.+'(([0-9]|.)+)'.+$/ лучше написать m/^.+'([\d.]+)'.+$/

Это сообщение отредактировал(а) ginnie - 22.1.2010, 15:37


--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
MZ412
Дата 22.1.2010, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Цитата

MZ412, и что, это у Вас правильно работает?

Кстати, вместо m/^.+'(([0-9]|.)+)'.+$/ лучше написать m/^.+'([\d.]+)'.+$/


Работает, т.к. единственная трабла была с нулевой скоростью.
Про улучшение регекспа понял, благодарю. Действительно более логично.
PM MAIL   Вверх
ginnie
Дата 22.1.2010, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Комодератор
Сообщений: 1287
Регистрация: 6.1.2008
Где: Москва

Репутация: 38
Всего: 49



Вот Ваш вариант, но покороче:

Код

while (<STDIN>) {
    if (/^.+'([\d.]+)'.+$/) {
        $input{speed}{$i} = $1;
        while (<STDIN>) {
            if (/^\s+(\d+)\s+$/) {
                $input{data}{$i++} = $1;
                last;
            }
        }
    }
}



--------------------
Написать код, понятный компьютеру, может каждый, но только хорошие программисты пишут код, понятный людям. (Мартин Фаулер. Рефакторинг)
PM MAIL Skype Jabber   Вверх
MZ412
Дата 22.1.2010, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 37
Регистрация: 4.12.2009

Репутация: нет
Всего: нет



Tnx! Очень здорово.
Просто и понятно.

Это сообщение отредактировал(а) MZ412 - 22.1.2010, 16:07
PM MAIL   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0873 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.