URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9848
[ Назад ]

Исходное сообщение
"  неопределенная переменная в perl"

Отправлено motorini , 23-Мрт-14 11:30 
здравствуйте.помогите, пожалуйста, с PERLовкой.есть вот такая строка:

id="545931" lat="48.7072377" lon="9.6465332" version="6" timestamp="2009-08-17T07:50:21Z" changeset="2174074" uid="110363" user="Frank9652";k="addr:city" v="Göppingen";k="addr:country" v="DE";k="addr:housename" v="Kreis-Medien-Zentrum & Radiofips";k="addr:housenumber" v="22";k="addr:postcode" v="73033";k="addr:street" v="Eberhardstraße"

после прогона через функцию

   sub parse {
      my($string)=@_;
      my $lat = "UnDefine";
      my $lon = "UnDefine";
      my $ort = "UnDefine";
      my $plz = "UnDefine";
      $csv = "";
      if ($string =~ m/"addr:postcode"/) {
         if ($string =~ m/"addr:city"/) {
            $string =~ s/<node //;
            $string =~ s/><tag//;
            $string =~ s/\/><tag//g;
            $string =~ s/\/>//;
            $string =~ s/ k/;k/g;
            #print $string."\n";
            my @arr = split(/;/,$string);
            foreach my $element (@arr) {
               my @L = split(/ /,$arr[0]);
               foreach my $l(@L) {
                  $L[1] =~ s/lat="//;
                  $L[1] =~ s/"//;
                  $lat = $L[1];
                  $L[2] =~ s/lon="//;
                  $L[2] =~ s/"//;
                  $lon = $L[2];
               }
               if ($element =~ m/"addr:city"/) {
                  for ($element) {
                     s/k="addr:city" v="//;
                     s/"//;
                  }
            #      #$element =~ s/k="addr:city" v="//;
            #      #$element =~ s/"//;
                  $ort = $element;
               }
               if ($element =~ m/"addr:postcode"/) {
                  for ($element) {
                     s/k="addr:postcode" v="//;
                     s/"//;
                  }
            #      #$element =~ s/k="addr:postcode" v="//;
            #      #$element =~ s/"//;
                  $plz = $element;
               }
               $csv = $lat.";".$lon.";".$plz.";".$ort."\n";
               #print $csv;
            }
         }
      }
      return $csv;
   }

переменные $plz и $ort оказываются undefined, причем случайным образом. то есть, при одном запуске срабатывает нормально, при другом лагает.
всем заранее спасибо.


Содержание

Сообщения в этом обсуждении
"  неопределенная переменная в perl"
Отправлено PavelR , 23-Мрт-14 11:56 
Это проще правильно переписать, чем исправить.

"  неопределенная переменная в perl"
Отправлено motorini , 23-Мрт-14 12:34 
> Это проще правильно переписать, чем исправить.

ну помогите если не трудно... c perl, честно говоря, не дружу..
тут беда в том, что позиция lat и lon в строке строго фиксирована, а вот addr:city и addr:postcode может быть где угодно...


"  неопределенная переменная в perl"
Отправлено михалыч , 23-Мрт-14 15:49 
>> Это проще правильно переписать, чем исправить.
> ну помогите если не трудно... c perl, честно говоря, не дружу..
> тут беда в том, что позиция lat и lon в строке строго
> фиксирована, а вот addr:city и addr:postcode может быть где угодно...

ну наворотил ))
держи


sub parse {
    my $string = shift;
    my $lat;
    my $lon;
    my $ort;
    my $plz;
    my $csv;

    $string =~ s/<node //;
    $string =~ s/><tag//;
    $string =~ s/\/><tag//g;
    $string =~ s/\/>//;
    $string =~ s/ k/;k/g;

    my @arr = split(/;/, $string);

    for (@arr) {
        if (/.*\slat="([0-9\.]+)"\slon="([0-9\.]+)"\s.*/) {$lat = $1; $lon = $2;}
        if (/.*city\"\sv="(.*)"/) {$ort = $1;}
        if (/.*postcode\"\sv="([0-9]+)"/) {$plz = $1;}
    }

    $csv = "$lat;$lon;$plz;$ort\n";
    return $csv;
}


вроде работает ))

"  неопределенная переменная в perl"
Отправлено motorini , 23-Мрт-14 18:57 
сейчас постоянно и для всего:

Use of uninitialized value $plz in concatenation (.) or string at ./db.pl line 40, <ALT> line 28119.
Use of uninitialized value $ort in concatenation (.) or string at ./db.pl line 40, <ALT> line 28119.
50.9704463;6.9207735;;

входящие строки имеют такой вид:

<node id="545931" lat="48.7072377" lon="9.6465332" version="6" timestamp="2009-08-17T07:50:21Z" changeset="2174074" uid="110363" user="Frank9652"><tag k="addr:city" v="Göppingen"/><tag k="addr:country" v="DE"/><tag k="addr:housename" v="Kreis-Medien-Zentrum & Radiofips"/><tag k="addr:housenumber" v="22"/><tag k="addr:postcode" v="73033"/><tag k="addr:street" v="Eberhardstraße"/>

<node id="661339" lat="48.1040226" lon="11.4882626" version="5" timestamp="2010-11-15T13:56:54Z" changeset="6377564" uid="65148" user="tixuwuoz"><tag k="addr:city" v="München"/><tag k="addr:country" v="DE"/><tag k="addr:housenumber" v="7"/><tag k="addr:postcode" v="81377"/><tag k="addr:street" v="Lorettoplatz"/><tag k="amenity" v="cafe"/><tag k="name" v="Cafe Jeanette"/>

<node id="5038192" lat="49.4107112" lon="12.485082" version="6" timestamp="2009-01-17T17:19:59Z" changeset="802191" uid="68329" user="Lord-K"><tag k="addr:city" v="Thanstein"/><tag k="addr:postcode" v="92554"/><tag k="is_in" v="Thanstein,Schwandorf,Oberpfalz,Bayern,Bundesrepublik Deutschland,Europe"/><tag k="name" v="Krähhof"/><tag k="openGeoDB:is_in" v="Thanstein,Schwandorf,Oberpfalz,Bayern,Bundesrepublik Deutschland,Europe"/><tag k="openGeoDB:postal_codes" v="92554"/><tag k="place" v="hamlet"/>

я думаю все это колдунство из-за неопределенной позиции addr:city i addr:postcode, а вот что делать, не знаю.. (


"  неопределенная переменная в perl"
Отправлено PavelR , 23-Мрт-14 19:22 

> вот что делать, не знаю.. (

Использовать готовые библиотеки. например XML::Simple, что-ли.


Приведенное решение было сделано под то, что вы написали в первом сообщении.
В последнем сообщении входные данные выглядят совершенно по-другому.

> я думаю все это колдунство из-за неопределенной позиции

я думаю, что всё это колдунство из-за того, что вам было пох на то, как отправилось ваше первое сообщение. Вы же писатель, а не читатель, читатели сами разберутся, "что я там накарябал".

Моя личная позиция такая: ваша невнимательность - ваши проблемы.


"  неопределенная переменная в perl"
Отправлено motorini , 23-Мрт-14 20:08 
$string =~ s/<node //;
$string =~ s/><tag//;
$string =~ s/\/><tag//g;
$string =~ s/\/>//;
$string =~ s/ k/;k/g;
это по поводу входных данных..

XML::Simple использовал.. размер обрабатываемого файла 35 GB и оно просто загибается..

в любом случае благодарю за конструктивный ответ.. )


"  неопределенная переменная в perl"
Отправлено михалыч , 23-Мрт-14 20:06 
Код абсолютно рабочий.
Проверил с вашими "сырыми" строками. Всё нормально.

> я думаю все это колдунство из-за неопределенной позиции addr:city i addr:postcode

Нет, не из-за этого.
У вас utf8. (addr:city Göppingen,München) Видите? Те строки, в которых utf8 нет, отрабатывают нормально?


"  неопределенная переменная в perl"
Отправлено motorini , 23-Мрт-14 20:52 
ваше решение все эти три строки работает правильно... и даже мое работает правильно с этими тремя строками... a полный входной файл не переваривает... я то ли в печали, то ли в бешенстве.. )))

"  неопределенная переменная в perl"
Отправлено михалыч , 23-Мрт-14 20:57 
> ваше решение все эти три строки работает правильно... и даже мое работает
> правильно с этими тремя строками... a полный входной файл не переваривает...
> я то ли в печали, то ли в бешенстве.. )))

Ну так я же вам и советую обратить внимание на то, что у вас данные хранятся в utf8
Те строки, в которых НЕТ символов utf8 нормально обрабатываются?


"  неопределенная переменная в perl"
Отправлено motorini , 23-Мрт-14 21:07 
да, нормально..
49.4107112;12.485082;92554;Thanstein

тогда что, размере файла дело?


"  неопределенная переменная в perl"
Отправлено motorini , 23-Мрт-14 21:23 
izvinite, stupil... pojdu na vyhodnyh dumat', kak ubrat' umljauty iz nemeckoj karty...
vse ravno spasibo Vam bol'shoe.. )
P.S. trudno na russkom nabirat', prostite...

"  неопределенная переменная в perl"
Отправлено михалыч , 23-Мрт-14 23:23 
Я не знаю как вы получаете входные данные, считываете их из БД или файла,
всего кода не вижу, в общем, копайте в сторону

use open IO => ":raw:utf8";
use open "IN" => ":bytes", "OUT" => ":utf8";

или
use open "IN" => ":encoding(cp850)", "OUT" => ":utf8", ":std";
или
binmode (STDIN, ":utf8");
binmode (STDOUT, ":utf8");

а можно так
binmode (STDOUT, ":encoding(utf8)");

открыть файловый манипулятор
open (my $fh, "<:utf8", $inputfile);

указать входную/выходную кодировку
open (my $inputfh, "<:encoding(cp850)", $inputfile);
open (my $outputfh, ">:encoding(ENCODING_NAME)", $outputfile);

а может только входную строку $string конвертировать достаточно?

тогда так
use Encode qw(encode decode);
$string = Encode::decode('koi8r', $string);

вариантов много, что-нибудь да получится


"  неопределенная переменная в perl"
Отправлено motorini , 24-Мрт-14 14:18 
eto file karty germanii ot openstreetmap...
ladno, budu da'she bodat'sja.. spasibo vam bol'shoe za podmogu.. )

"  неопределенная переменная в perl"
Отправлено михалыч , 24-Мрт-14 16:58 
> eto file karty germanii ot openstreetmap...
> ladno, budu da'she bodat'sja.. spasibo vam bol'shoe za podmogu.. )

посмотрите ещё здесь, может поможет
http://stackoverflow.com/questions/16693769/encoding-german-...
http://stackoverflow.com/questions/14478325/using-sed-to-rep...
http://www.perlmonks.org/?node_id=895659


"  неопределенная переменная в perl"
Отправлено motorini , 26-Мрт-14 13:42 
sdelal vot tak:

    sub parse {
        my($string)=@_;
        my $lat = "UnDefine";
        my $lon = "UnDefine";
        my $ort = "UnDefine";
        my $plz = "UnDefine";
        $csv = "";
        if ($string =~ m/"addr:postcode"/) {
            if ($string =~ m/"addr:city"/) {
                $string =~ s/<node //;
                $string =~ s/><tag//;
                $string =~ s/\/><tag//g;
                $string =~ s/\/>//;
                $string =~ s/ k/;k/g;
                my @arr = split(/;/,$string);
                for (@arr) {
                    if (/.*\slat="([0-9\.]+)"\slon="([0-9\.]+)"\s.*/) {$lat = $1; $lon = $2;}
                    if (/.*city\"\sv="(.*)"/) {$ort = $1;}
                    if (/.*postcode\"\sv="([0-9]+)"/) {$plz = $1;}
                }
                $csv = $lat.";".$lon.";".$plz.";".$ort."\n";
            }
        }
        return $csv;
    }

molotit kak chasy.. ) spasibo ogromnoe.. s menja pivo pri sluchae.. )


"  неопределенная переменная в perl"
Отправлено михалыч , 26-Мрт-14 15:04 
> spasibo ogromnoe.. s menja pivo pri sluchae.. )

хорошо, договорились, пивка попьём,
будете у нас на Колыме - милости просим! ))


"  неопределенная переменная в perl"
Отправлено motorini , 26-Мрт-14 23:41 
net uzh, luchshe vy k nam... )))