Merhaba,
Baş belası UTF ile çok basit bir yerde acemice takıldım!
Not: Burada amaç, boşluklarla ayrılmış sözcükleri ayırmak (split) değil UTF ile ayağımız dolanmadan saymak ve/veya dilimlemektir.
Aşağıdaki işlev, bir başlangıç noktasından itibaren aralık (range) üzerinde ilerleyerek (burada bir dizge) boşluk karakter görene kadar aralığı tüketiyor ve her adımı sayıyor. Eğer tüm karakterler sıradan ASCII ise sorun yok. Ama örnekteki "iki" ve "beş" dizgeleri ile arasında fark var: "beş", 4 bayttan oluşan bir dizgedir.
Yani elde ettiğiniz sıra bilgisini dilimlemek için kullanırsanız hata edersiniz, çünkü aralığı dchar olarak yani UTF uyumlu karakterler biçimde tüketiyoruz. Dolayısıyla ekran çıktılarından görüleceği üzere "iki" doğru bir şekilde dilimlenirken, "beş" için aynı şeyi söyleyemeyiz, farklı karakterler çıkacaktır.
auto walkToFirstSpace(R)(R range, size_t start)
{
import std.range, std.utf, std.conv;
string r = range[start..$];
size_t counter;
for(; !r.empty; r.popFront())
{
if(r.front == ' ')
{
break;
}
else
{
counter++;/*
auto str = r.front.to!string;
auto chr = str.byCodeUnit;
if(chr.length > 1) counter += chr.length;
else counter++;//*/
}
}
return counter;
}
auto str2 = "bunlar iki elma";
auto str5 = "bunlar beş elma";
enum index = 0;
void main()
{
import std.stdio;
// ilk sözcük:
str2.walkToFirstSpace(index).writeln; // 6
str5.walkToFirstSpace(index).writeln; // 6
str2[0..6].writefln!"[%s]"; // [bunlar]
str5[0..6].writefln!"[%s]"; // [bunlar]
// ikinci sözcük
str2.walkToFirstSpace(index + 7).writeln; // 3
str5.walkToFirstSpace(index + 7).writeln; // 3
str2[7..10].writefln!"[%s]"; // [iki]
str5[7..11].writefln!"[%s]"; // [be�]
}
Normalde ikinci sözcüğün üzerinde dans ederken edindiğimiz bilgi str2 için 3, str5 için 4 olması gerekirdi. Bunu yapabilmek için byCodeUnit'i kullandım. Saçma şekilde to ile string'e çevirdim sonra if'le sorguladım. Ama bu çok acemice sanki. Aslında dchar bilgiye ihtiyaç duymasam pekala aralığı byCodeUnit ile de tükebilirdim ama boşluk karakterine benzeyen şeyler karşımız çıkacaktır.
Özetle bu duruma alternatif önerebilecek var mı?
Sevgiler, saygılar...