Forum: Ders Arası RSS
Belirli bir dosya formatıyla biçimlendirilmiş dosyayı okumak
Sayfa:  1  2  sonraki 
erdem (Moderatör) #1
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Konu adı: Belirli bir dosya formatıyla biçimlendirilmiş dosyayı okumak
Bu soruya aslında başka bir programlama dili ile ilgili başka bir forumda rastladım. Sonuçta biz de neredeyse bu işlemin tersi olan XmlElemanı oluşturduğumuz için ilgimi çekti. Ama buradaki bilgi tam bir XmlElemanı değil.

Ben de aynı işlemi D'de nasıl yapabilirdik diye düşündüm. Amacımız bize verilen bu tür bir metin dosyasını okumak. Aynı XML elemanlarında olduğu gibi etiketler birbirinin içine girebiliyor.

<b>matematige benzer</b> sekilde <u>bilgisayar</u> bilimi bilginin, <p>ozellikle elektronik
makineler araciligiyla</p> duzenli ve ussal bicimde islenmesi bilimidir. <h>bunun yani sira</h>
bilgisayar bilimi bilgi islemlerinde uygulanabilen matematiksel yapilari da inceler. <u>amaci ve
<b>gorevi</b></u> bir <b><u>yandan</u></b> temel <b><p>aksiyomatik</p></b>
matematiksel <p><b>kuramlar</b></p> uretmek, ikinci olarak tum diger uzmanlik dallarinin
nesnelerini ve sureclerini cozumleyip soyut matematiksel yapilara ve algoritmalara
donusturmek ve <h><p><u><b>ucuncu olarak</b></u></p></h> soyut matematiksel yapilarin
aktarilabilecegi, saklanabilecegi ve algoritmalarla otomatik olarak islenebilecegi matematiksel
makinalari tasarlamaktir.

Okuduktan sonra amacımız bu dosyayı tekrar ekrana:

<u></u> arası büyük harfle
<b></b> arası koyu harfle ~ [koyu kısmını örneğin metin merhaba ise mmeerrhhaabbaa şeklinde tekrarlı yazıyoruz. konsolda koyu yazmanın bir yolu olmadığı için]
<h></h> arası gizli - bu kısmı yazdırmıyoruz
<p></p> arası köşeli parantezlerle

yazdırmak. Ayrıca eğer giriş dosyasında kapanmamış bir etiket varsa kullanıcıyı bilgi verdikten sonra bir hata atmak.

Benim aklıma şu tür bir çözüm geldi. Bir Yazıcı nesnemiz olur <b> etiketine rastladığı zaman özellikler koyu yazmayı aç ya da </h> etiketine geldiği zaman özellikler gizli yazmayı kapat diyebilir.

Daha başka da çözüm yolları olabilir ama hızlı bir çözüm bulamadım  :rolleyes:

Aklınıza gelen hızlı bir çözüm yöntemi var mı acaba ?..
erdem (Moderatör) #2
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Parçalama işlemini çabukça böyle yazdım :)
import std.stdio, std.string, std.algorithm;
 
void main() {
    File giriş = File("deneme.txt", "r");
    string[] kelimeler;
    
    while (!giriş.eof) {
        string satır = chomp(giriş.readln());
        auto parçalar = splitter(satır, ' ');
        
        foreach(parça; parçalar)
            kelimeler ~= parça;
    }
 
    foreach(kelime; kelimeler)
        writeln(kelime);
}
acehreli (Moderatör) #3
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Birazcık daha kısa yazabildim:

import std.stdio, std.string, std.algorithm;
 
void main() {
    File giriş = File("deneme.txt", "r");
    string[] kelimeler;
 
    foreach (string satır; lines(giriş)) {
        kelimeler ~= split(chomp(satır));
    }
 
    writeln(kelimeler);
}

Ali
erdem (Moderatör) #4
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Asıl soru bundan sonra nasıl bir mantık izleyeceğiz :)
Kadir Can #5
Üye Haz 2010 tarihinden beri · 413 mesaj
Grup üyelikleri: Üyeler
Profili göster · Bu konuya bağlantı
Mantık bence böyle olmalı:
-Karakter kontrol edilmeli;Eğer "<" karakterine rastlanırsa ">" gelene kadar arada kalan ifade alınmalı.
-İfade alındıktan sonra kapama kontrolü yine aynı şekilde yapılmalı.
-Kapatma olmadıysa hata atılmalı.
-Kapatma yapıldıysa uygun işlem bulunmalı ("b" için kalınlaştırma gibi).Burada switch case kullanılabilir.
-Koyu harf dışında hepsinin çaresi var.Koyu harfle ilgili bir fikrim yok.

Acaba nasıl olabilir?
acehreli (Moderatör) #6
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Düzen bilgisinin ne oluşturacağı metnin gösterileceği ortama bağlı. O yüzden burada iki genel iş var:

- girişi ayrıştırmak ve bir DüzenliMetin oluşturmak

- DüzenliMetin'i belirli bir çıkış düzenleyicisi ile kullanmak

    /* Ayrıştırma */
    auto metin = new DüzenliMetin(/* ... */);
 
    auto konsol = new KonsolDüzenleyicisi();
    konsol.göster(metin);
 
    auto xml = new XmlDüzenleyicisi("cikis_dosyasi.xml");
    xml.göster(metin);
 
    auto özel = new BenimÖzelDüzenleyicim(/* ... */);
    özel.göster(metin);

Her bir düzenleyici ne yapacağını kendisi bilir. (Emin konuşuyorum ama emin değilim! :) Burada "double-dispatch" var, çünkü davranış iki açıdan esnek: Hem düzenleyici hem de metin parçaları çalışma zamanında bilinebiliyorlar.)

Ali
erdem (Moderatör) #7
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #5
Kadir Can:
-Koyu harf dışında hepsinin çaresi var.Koyu harfle ilgili bir fikrim yok.
Acaba nasıl olabilir?

Bence herkes bir çözüm yazsın sonra çözümleri karşılaştıralım  ;-)

Koyu harfleri zaten koyu yapmaya gerek yok. Örneğin <b>koyu</b> ise çıktı olarak kkooyyuu vermesi yeterli oluyor.

acehreli:
- girişi ayrıştırmak ve bir DüzenliMetin oluşturmak

Düzenli metin derken regexp'den bahsediyorsunuz sanırım. Benim en zorlandığım konulardan bir tanesi :( Burada bazı bilgiler var ama örnekler yetersiz kalıyor.

http://www.digitalmars.com/d/2.0/regular-expression.html

if (std.regexp.find(s, "/<"))
        writeln("buldum");
    else writeln("bulamadım");

Bir şeyler denedim ama ilk planda yapmaya çalışacağımız şey şunun gibi olacak değil mi.
<b>matematige benzer</b>
sekilde
<u>bilgisayar</u>
bilimi bilginin,
<p>ozellikle elektronik makineler araciligiyla</p>

Daha sonra düzenli ifadeler kullanarak bunları parça parça alacağız. Ama etiketler birbirinin içine girince biraz işler karışıyor.

<u>amaci ve<b>gorevi</b></u>
 bir
 <b><u>yandan</u></b>
 temel
<b><p>aksiyomatik</p></b>
matematiksel
   
acehreli:
    /* Ayrıştırma */
    auto konsol = new KonsolDüzenleyicisi();
    konsol.göster(metin);

Umarım burada gerçek konsolun çıktısını değiştirmekten bahsetmiyorsunuzdur :D
acehreli (Moderatör) #8
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
erdem:
acehreli:
- girişi ayrıştırmak ve bir DüzenliMetin oluşturmak

Düzenli metin derken regexp'den bahsediyorsunuz sanırım.

Hayır. Metin okunmuş ve şurası koyudur, burası eğiktir diye anlaşılmış. Yani metin, ama düzeni de var.

acehreli:
    /* Ayrıştırma */
    auto konsol = new KonsolDüzenleyicisi();
    konsol.göster(metin);

Umarım burada gerçek konsolun çıktısını değiştirmekten bahsetmiyorsunuzdur :D

Okunup anlaşılmış olan ve düzenini de içeren metni konsolda göstermeye çalışıyorum. Konsolda da koyu, eğik, vs. metin gösterilebilir. Koyu font kullanılabileceği gibi, belirli renkler de kullanılabiliyor.

Benim söylemek istediğim, burada iki konu var:

- gelen metni okumak ve düzenini ifade eden bir yapıda saklamak ("yapı" ile struct demek istemiyorum; herhangi başka biçimde de olabilir)

- o yapıdaki metni, ortamına göre farklı biçimlerde göstermek

Ali
acehreli (Moderatör) #9
Kullanıcı başlığı: Ali Çehreli
Üye Haz 2009 tarihinden beri · 4527 mesaj
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #7
erdem:
regexp'den bahsediyorsunuz sanırım.

Vakit bulduğunda şuradaki yazıya bakar mısın; D2 ile uyumlu mu?

  http://ddili.org/makale/duzenli_ifadeler.html

D1 için yazılmış olduğunu biliyorum; D2 başkaysa düzeltelim.

Ali
erdem (Moderatör) #10
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
acehreli:
Vakit bulduğunda şuradaki yazıya bakar mısın; D2 ile uyumlu mu?

Tabi. Büyük bir zevkle :)

İlk planda aklıma böyle basit bir enum kullanmak geldi. Gizli metinlerin yazdırılmadığını düşünürsek.
enum Biçim { Yok, Koyu = 10, Gizli, Köşeli, Büyük,
        KoyuKöşeli = 22, KoyuBüyük, 
        Hepsi = 45 } 
    
class DüzenliMetin {
    string metin;
    Biçim biçim;
 
    this(string metin, Biçim biçim) {
        this.metin = metin;
        this.biçim = biçim;
    }        
}
 
void main() {
 
// ...
 
    foreach (kelime; kelimeler) {
        if (kelime.length >= 3)
            auto baştakiEtiket = kelime[0 .. 3];
        writeln(kelime);
    }
 
    auto metin = new DüzenliMetin("matematige", Biçim.KoyuKöşeli);
}
Bu mesaj 2 defa değişti; son değiştiren: erdem; zaman: 2011-05-03, 16:48.
erdem (Moderatör) #11
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #9
acehreli:
erdem:
regexp'den bahsediyorsunuz sanırım.

Vakit bulduğunda şuradaki yazıya bakar mısın; D2 ile uyumlu mu?

  http://ddili.org/makale/duzenli_ifadeler.html

Maalesef çoktan deprecated olmuş. Hatta o makaye de bir uyarı eklemenin zamanı gelmiş sanırım :)

Şu anda std.regex kullanılıyor.

http://www.digitalmars.com/d/2.0/phobos/std_regex.html

Ben biraz oynamaya başladım. Ve şöyle şeyler çıktı. Bana aslında daha kullanışlı gibi geldi.

import std.string, std.stdio, std.regex;
 
void main() {
    auto s = "kedi-köpek";
 
    auto r = match(s, regex("köpek"));
 
    // bulunan ifadeden bir önceki parçayı gösteren bir dilim döndürür
    auto önceki = r.pre;
    
    auto s1 = s[0 .. 5];   // kedi-
    assert(önceki == s1);
 
    // bulunan ifadeden bir sonraki parçayı gösteren bir dilim döndürür
    auto sonraki = r.post;
    auto s2 = s[$ ..$];
    assert(sonraki == s2); // <boş>
 
    // bulunan ifadeyi gösteren bir dilim döndürür
    auto bulunan = r.hit;
    auto s3 = s[5 .. $];
    assert(bulunan == s3); // köpek
}
Bu mesaj erdem tarafından değiştirildi; zaman: 2011-05-04, 01:24.
erdem (Moderatör) #12
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Bu şekilde etiketleri de arayıp istediğimiz metni elde edebiliyoruz.

    auto dizi ="<b>matematiğe benzer</b>";
 
    auto r1 = match(dizi, regex("<.>"));
    dizi = r1.post;
    
    auto r2 = match(dizi, regex("</.>"));
    dizi = r2.pre;
    
    writeln(r1.hit);
    writeln(r2.hit);
 
    writeln("dizinin son durumu:", dizi);
Mengu (Moderatör) #13
Kullanıcı başlığı: NONSERVIAM
Üye Tem 2009 tarihinden beri · 347 mesaj · Konum: Dersaadet
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
erdem:
Bu şekilde etiketleri de arayıp istediğimiz metni elde edebiliyoruz.

    auto dizi ="<b>matematiğe benzer</b>";
 
    auto r1 = match(dizi, regex("<.>"));
    dizi = r1.post;
    
    auto r2 = match(dizi, regex("</.>"));
    dizi = r2.pre;
    
    writeln(r1.hit);
    writeln(r2.hit);
 
    writeln("dizinin son durumu:", dizi);

regex ile html parse etmek hic tavsiye edilmiyor, onun yerine html parserlar tavsiye ediliyor.
http://www.mengu.net - some kind of monster
erdem (Moderatör) #14
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #12
Metni ayrıştırma kısmı da şık bir çözüm olmasa da şunun gibi oldu:

import std.string, std.stdio, std.regex;
 
string[] düzenlimetin;
 
void ayrıştır (string şimdiki, string sonraki) {
 
    string sonuç = şimdiki;
tekrar:
    auto başlangıç = match(sonuç, regex("<.>"));
    auto bitiş = match(sonuç, regex("</.>"));
    
    if (!başlangıç.empty
        &&
        !bitiş.empty) {
        sonuç = başlangıç.post;
        bitiş = match(sonuç, regex("</.>"));
        sonuç = bitiş.pre;
 
        // .. aşağıdakinin aynısı
        düzenlimetin ~= sonuç;
 
    } else if (!başlangıç.empty
               &&
               bitiş.empty) {
        sonuç ~= " " ~ sonraki;
        goto tekrar;
    } else {
        düzenlimetin ~= sonuç;
        // aslında buraya DüzenliMetin'i oluşturan kod gelecek
    }
}
 
void main() {
 
    auto s4  = "<b>matematige";
    auto s5  = "benzer</b>";
    auto s6  = "sekilde";
    auto s7  = "<u>bilgisayar</u>";
    auto s8  = "bilimi";
    auto s9  = "bilginin,";
    auto s10 = "<p>ozellikle";
    auto s11 = "elektronik";
    auto s12 = "makineler";
    auto s13 = "araciligiyla</p>";
 
    ayrıştır(s4, s5);
 
    writeln("Düzenlenmiş:", düzenlimetin);
}

Burada for döngüsünde bir sonraki kelimeye de erişebileceğimizi düşünerek yazdım.
    foreach (kelime; kelimeler) {
// ...        
    }
Umarım erişebiliyoruzdur :)
erdem (Moderatör) #15
Üye Tem 2009 tarihinden beri · 981 mesaj · Konum: Eskişehir
Grup üyelikleri: Genel Moderatörler, Üyeler
Profili göster · Bu konuya bağlantı
Yanıtlanan mesaj #13
Mengu:
regex ile html parse etmek hic tavsiye edilmiyor, onun yerine html parserlar tavsiye ediliyor.
Bir örnek yazabilirsen sevinirim.

Bir de aslında bu bir html dökümanı değil. Html ile metin'in karışımı gibi bir şey :D
Doğrulama Kodu: VeriCode Lütfen resimde gördüğünüz doğrulama kodunu girin:
İfadeler: :-) ;-) :-D :-p :blush: :cool: :rolleyes: :huh: :-/ <_< :-( :'( :#: :scared: 8-( :nuts: :-O
Özel Karakterler:
Sayfa:  1  2  sonraki 
Forum: Ders Arası RSS
Bağlı değilsiniz. · Şifremi unuttum · ÜYELİK
This board is powered by the Unclassified NewsBoard software, 20100516-dev, © 2003-10 by Yves Goergen
Şu an: 2017-11-21, 15:19:49 (UTC -08:00)