Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Извлечение строк из определенного интервала


Автор: shtuceron 9.10.2011, 12:29
Здравствуйте, на сайте http://valera.asf.ru/perl/cookbook/cont.php?id=80 есть интересная конструкция

Код

while (<>) {
  if (/НАЧАЛЬНЫЙ ШАБЛОН/../КОНЕЧНЫЙ ШАБЛОН/) {
  # Строка находится между начальным
  # и конечным шаблонами включительно.
  }
}

while (<>) {
  if ($НОМЕР_НАЧАЛЬНОЙ_СТРОКИ .. $НОМЕР_КОНЕЧНОЙ_СТРОКИ) {
  # Строка находится между начальной
  # и конечной включительно.
  }
}


Как можно получить саму строку чтобы продолжить работать с ней?

Спасибо!

Автор: Pfailed 9.10.2011, 14:37
Цитата(shtuceron @  9.10.2011,  12:29 Найти цитируемый пост)
Как можно получить саму строку чтобы продолжить работать с ней?

Начальную, конечную или какую?

Автор: shtuceron 9.10.2011, 14:53
которая находится между /НАЧАЛЬНЫЙ ШАБЛОН/../КОНЕЧНЫЙ ШАБЛОН/

Автор: Pfailed 9.10.2011, 15:45
Ну первое что приходит в голову
Код

while (<>) {
  if (/НАЧАЛЬНЫЙ ШАБЛОН/../КОНЕЧНЫЙ ШАБЛОН/) {
    unless (/НАЧАЛЬНЫЙ ШАБЛОН/ || /КОНЕЧНЫЙ ШАБЛОН/) {
      # Строка находится между начальным
      # и конечным шаблонами не включительно.
    }  
  }
}


Автор: shtuceron 9.10.2011, 15:54
Правильно ли я понимаю что при чтении файла конструкция вида
Код

while (<>)
{
}


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

Автор: Pfailed 9.10.2011, 16:01
Сработает, вы почитайте по вашей же ссылке из первого поста.

Автор: shtuceron 9.10.2011, 16:25
Спасибо

но пока не все получается)

я взяз для примера xml файл:
Код

<?xml version='1.0'?>
<opt id="one">
  <name>tom</name>
  <name>bob</name>
  <name>harry</name>
</opt>


и пытаюсь его обработать:
Код

while(<>)
{
  if (/<name>/../<\/name>/) {
    unless (/<name>/ || /<\/name>/) {
      print $_;
    }  
  }
}


на выходе я ничего не получаю:
совсем не то что я жду, как же достучаться до имен???

Автор: Pfailed 9.10.2011, 17:29
Это потому что начальный шаблон и конечный и то что между ними на одной строке.
Эта конструкция сработает для случаев когда строка между шаблонами не будет содержаться в строке с начальным или конечным шаблоном. Например:
Код

<name>
tom
</name>



Цитата(shtuceron @  9.10.2011,  16:25 Найти цитируемый пост)
как же достучаться до имен???

Я надеюсь вы знаете про существование XML парсеров?

С оператором диапазона можно сделать что-нибудь такое
Код

while (<>) {
    if (/<name>/../<\/name>/) {
        if (/<name>(.+?)<\/name>/ || /<name>(.+)/ || /(.+?)<\/name>/) {
            print $1, "\n";
        }
        elsif (!/<name>/ && !/<\/name>/) {
            print;
        }
    }
}

Но это уже слишком громоздко. Советую поискать альтернативные пути, если это XML, то средств достаточно.

Автор: shtuceron 9.10.2011, 17:41
Цитата

Я надеюсь вы знаете про существование XML парсеров?


Знаком, но не знаком ни с одним который бы мог вносить исправления по выбранным мною узлам (добавление/удаление/исправление атрибута или текстовому блоку) и сохранять исправления без обхода остальных узлов.

XML::Simple читает весь xml в хеш, но ходить по нему (если я не знаю структуры xml документа) у меня почему то не получается(

Пытаюсь делать так
Код

 foreach $key (keys %data)
 {
    print $key,"\n";
 }


ничего не происходит.

Автор: alezzz 9.10.2011, 18:30
если не ошибаюсь то XML::Simple возвращает не хеш а ссылку (reference ) на хеш, почитайте внимательнее документацию, там есть примеры с испольхованием Data::Dumper;

Автор: Pfailed 9.10.2011, 18:32
Цитата(shtuceron @  9.10.2011,  17:41 Найти цитируемый пост)
Знаком, но не знаком ни с одним который бы мог вносить исправления по выбранным мною узлам

Посмотрите http://www.perlmonks.org/?node_id=712472
Помимо этого в документации XML::LibXML сказано
Цитата

XML::LibXML provides an light-wight interface to modify a node of the document

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)