здравствуйте.помогите, пожалуйста, с 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, причем случайным образом. то есть, при одном запуске срабатывает нормально, при другом лагает.
всем заранее спасибо.
Это проще правильно переписать, чем исправить.
> Это проще правильно переписать, чем исправить.ну помогите если не трудно... c perl, честно говоря, не дружу..
тут беда в том, что позиция lat и lon в строке строго фиксирована, а вот addr:city и addr:postcode может быть где угодно...
>> Это проще правильно переписать, чем исправить.
> ну помогите если не трудно... 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;
}
вроде работает ))
сейчас постоянно и для всего: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, а вот что делать, не знаю.. (
> вот что делать, не знаю.. (Использовать готовые библиотеки. например XML::Simple, что-ли.
Приведенное решение было сделано под то, что вы написали в первом сообщении.
В последнем сообщении входные данные выглядят совершенно по-другому.> я думаю все это колдунство из-за неопределенной позиции
я думаю, что всё это колдунство из-за того, что вам было пох на то, как отправилось ваше первое сообщение. Вы же писатель, а не читатель, читатели сами разберутся, "что я там накарябал".
Моя личная позиция такая: ваша невнимательность - ваши проблемы.
$string =~ s/<node //;
$string =~ s/><tag//;
$string =~ s/\/><tag//g;
$string =~ s/\/>//;
$string =~ s/ k/;k/g;
это по поводу входных данных..XML::Simple использовал.. размер обрабатываемого файла 35 GB и оно просто загибается..
в любом случае благодарю за конструктивный ответ.. )
Код абсолютно рабочий.
Проверил с вашими "сырыми" строками. Всё нормально.> я думаю все это колдунство из-за неопределенной позиции addr:city i addr:postcode
Нет, не из-за этого.
У вас utf8. (addr:city Göppingen,München) Видите? Те строки, в которых utf8 нет, отрабатывают нормально?
ваше решение все эти три строки работает правильно... и даже мое работает правильно с этими тремя строками... a полный входной файл не переваривает... я то ли в печали, то ли в бешенстве.. )))
> ваше решение все эти три строки работает правильно... и даже мое работает
> правильно с этими тремя строками... a полный входной файл не переваривает...
> я то ли в печали, то ли в бешенстве.. )))Ну так я же вам и советую обратить внимание на то, что у вас данные хранятся в utf8
Те строки, в которых НЕТ символов utf8 нормально обрабатываются?
да, нормально..
49.4107112;12.485082;92554;Thansteinтогда что, размере файла дело?
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...
Я не знаю как вы получаете входные данные, считываете их из БД или файла,
всего кода не вижу, в общем, копайте в сторону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);вариантов много, что-нибудь да получится
eto file karty germanii ot openstreetmap...
ladno, budu da'she bodat'sja.. spasibo vam bol'shoe za podmogu.. )
> 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
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.. )
> spasibo ogromnoe.. s menja pivo pri sluchae.. )хорошо, договорились, пивка попьём,
будете у нас на Колыме - милости просим! ))
net uzh, luchshe vy k nam... )))