November 09, 2020

(Ali'nin düzeltmesi: Pencereye sığsınlar diye uzun satırları böldüm.)

Ben pythondan gelen şöyle bir şeyi parse ediyordum.

auto bir = "[[0.1412412 0.6006437 0.2581151]];[[0.10179551 0.55824722 0.33995727]];" ~
                       "[[0.07045269 0.57505688 0.35449043]]";

double[][] doubleList = bir .split(";").map!( a=> a[1..$-1].replace(" ", ",")
                       .to!(double[]) ).array;

Mutluydum. Ama python tarafındaki değişikliklerimden sonra python arada sırada şöyle şeyler yollamaya başladı.

   auto iki =  "[[9.96691427e-01 1.81034963e-04 3.12753774e-03]];" ~
     "[[0.40397309 0.2163366  0.3796903 ]];[[9.95962058e-01 1.78231597e-04 3.85970996e-03]]";

Dikkat ederseniz " 0.3796903 ]" Başında fazladan bir tane boşluk ve parantezden önce bir fazla boşluk daha var.

Biraz ninjalık yaptım:

   double[][] doubleList = iki.split(";").map!( a=> a[1..$-1].replace("  ", " ")
                                 .replace(" ]", "]").replace(" ", ",").to!(double[]) ).array;

Sonra şöyle şeyler olduğunun farkına vardım

[[0.00173973 0.05457028 0.94369 ]] -> "]" beklerken " ]"(iki boşluk) gelmiş. Ben " ]" için koruma almıştım

Yani artık python tarafından mı zmq 'den mi belli belirsiz sayıda fazla boşluk geliyor.

Acaba Regex veya std'deki bir fonksiyon ile döngüsüz bir çözüm varmıdır? Ben döngü dönüyorum şimdi.

Erdemdem

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

November 09, 2020

Şöyle:

 auto r = regex(` *\[ *\[ *(.*) *\] *\]`);

 double[][] sonuç;
 foreach (s; iki.splitter(';')) {
   foreach (m; s.matchAll(r)) {
     sonuç ~= splitter(m[1]).map!(to!double).array;
   }
 }
 writeln(sonuç);

regex içindeki " " bölümleri "sıfır veya daha fazla boşluk" anlamına geliyor. '(.)' biçiminde parantezlenmiş olan bölüm daha sonra 'm[1]' ifadesinde kullanılacak olan "birinci" seçilmiş dizgi oluyor.

En önemli yerlerinden birisi, '.splitter' diye değil, 'splitter(/.../)' diye çağrılan yer. O, birden fazla boşluğu otomatik olarak atlıyormuş. Şurada "merged together" diyen yer:

https://dlang.org/library/std/algorithm/iteration/splitter.html

Bütün ifade aralık olarak şöyle yazılabiliyor:

 auto sonuç = iki
              .splitter(';')
              .map!(s => s
                         .matchAll(r)
                         .map!(m => splitter(m[1])
                                    .map!(to!double)
                                    .array))
              .joiner;

Sondaki '.joiner' yerine '.array' kullanıldığında senin istediğin 'double[][]' olacak.

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]