Yazım Kontrol Uygulaması

1 7

Bu yazıda beraber C# ile basit bir Türkçe yazım kontrolü aracı oluşturacağız. Aracımız Microsoft Office Programlarında olduğu gibi kelimemizi kontrol edip eğer kelimemiz hatalıysa altını çizecek. metin tabanlı uygulamalarda kullanabileceğiniz bu örnek uygulama çok kişinin işine yarayacaktır.

Kelime yazım kontrolünde kullanacağımız kontrol sınıfı Phyton ile  kodlanmış Spell Corrector aracının C# a dönüştürülmüş hali. http://norvig.com/spell-correct.html adresinden ulaşabileceğiniz bu basit uygulama Phyton ile sadece 21 satır kod ile tamamlanmış. (Boşlukları saymadan)

Python ile yazılmış kodun tamamını şu şekilde.

import re, collections

def words(text): return re.findall('[a-z]+', text.lower()) 

def train(features):
    model = collections.defaultdict(lambda: 1)
    for f in features:
        model[f] += 1
    return model

NWORDS = train(words(file('big.txt').read()))

alphabet = 'abcdefghijklmnopqrstuvwxyz'

def edits1(word):
   splits     = [(word[:i], word[i:]) for i in range(len(word) + 1)]
   deletes    = [a + b[1:] for a, b in splits if b]
   transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
   replaces   = [a + c + b[1:] for a, b in splits for c in alphabet if b]
   inserts    = [a + c + b     for a, b in splits for c in alphabet]
   return set(deletes + transposes + replaces + inserts)

def known_edits2(word):
    return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)

def known(words): return set(w for w in words if w in NWORDS)

def correct(word):
    candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
    return max(candidates, key=NWORDS.get)

Phyton kodunu şu şekilde kullanıyoruz.

>>> correct('speling')
'spelling'
>>> correct('korrecter')
'corrector'

Kodun açıklamasını yukarıda verdiğim linkte okuyabilirsiniz. (İngilizce) Ve yine bu kodun diğer programlama dillerinde yazılmış halleride yine aynı sayfada bulunuyor.

LanguageLines
Code
Author
(and link to implementation)
Awk15Tiago “PacMan” Peczenyj
Awk28Gregory Grefenstette
C184Marcelo Toledo
C++98Felipe Farinon
C#43Lorenzo Stoakes
C#69Frederic Torres
Clojure18Rich Hickey
D23Leonardo M
Erlang87Federico Feroldi
F#16Dejan Jelovic
F#34Sebastian G
Go57Yi Wang
Groovy22Rael Cunha
Haskell24Grzegorz
Java35Rael Cunha
Java372Dominik Schulz
Javascript92Shine Xavier
Javascript53Panagiotis Astithas
Lisp26Mikael Jansson
Perl63riffraff
PHP68Felipe Ribeiro
PHP103Joe Sanders
Python21Peter Norvig
Rebol133Cyphre
Ruby34Brian Adkins
Scala23Thomas Jung
Scheme45Shiro
Scheme89Jens Axel

Ben C# için bu kodun uyarlamasını kullanacağım. http://frederictorres.blogspot.com/2011/04/how-to-write-spelling-corrector-from.html adresindeki kodu kullanacağız uygulamamızı türkçeleştirmekle başlayalım. Bu kodun çalışması için projemize DinamicSugar kütüphanelerini dahil etmeliyiz.

Nuget manager ile DynamicSugar Kütüphanesini Kurmak için
(1) Menu Tools -> Library Package Manager -> Library Package Console
(2) Install-package DynamicSugar
(3) Paste the code in the file program.cs above the program class
(4) Aşağıdaki 2 using satırını ekleyin.
using System.Threading.Tasks;
using DynamicSugar;

class SpellCorrector
{

Dictionary<string, int> DWORDS;
const string ALPHABET = "abcçdefgğhıijklmnoöpqrsştuüvwxyz";//Türkçe Karakterleri ekliyoruz

public SpellCorrector()
{

DWORDS = this.Train(this.Words(System.IO.File.ReadAllText("tr.txt")));//tr.txt dosyası bizim türkçe kelimelerin yer aldığı listemiz.
}
List<string> Words(string text)
{

return Regex.Matches(text.ToLower(), "[a-zığüşöç]+").ToList(); //Türkçe Karakterleri ekliyoruz
}
Dictionary<string, int> Train(List<string> features)
{

var model = new Dictionary<string, int>();
foreach (var f in features)
model[f] = model.Get(f, 0) + 1;
return model;
}
class StringPair
{

public string a, b;
}
List<string> Edits1(string word)
{

var splits = DS.Range(word.Length + 1).Map(i => new StringPair { a = word.Slice(0, i), b = word.Slice(i) });
var deletes = splits.Map(s => s.a + s.b.Slice(1));
var transposes = splits.Map(s => s.b.Length > 1 ? s.a + s.b[1] + s.b[0] + s.b.Slice(2) : "**");

var replaces = new List<string>();
foreach (var s in splits)
foreach (var c in ALPHABET)
if (s.b.Length > 0)
replaces.Add(s.a + c + s.b.Slice(1, -1));

var inserts = new List<string>();
foreach (var s in splits)
foreach (var c in ALPHABET)
inserts.Add(s.a + c + s.b);

return deletes.Add(transposes).Add(replaces).Add(inserts);
}
List<string> KnownEdits2(string word)
{

var l = new List<string>();
foreach (var e1 in this.Edits1(word))
foreach (var e2 in Edits1(e1))
if (this.DWORDS.ContainsKey(e2))
l.Add(e2);
return l;
}
List<string> Known(List<string> words)
{

return words.Filter(w => this.DWORDS.ContainsKey(w));
}
public string Correct(string word)
{

var candidateWords = this.Known(DS.List(word));
if (candidateWords.Count == 0)
candidateWords = this.Known(this.Edits1(word));
if (candidateWords.Count == 0)
candidateWords = this.KnownEdits2(word);
if (candidateWords.Count == 0)
candidateWords = DS.List(word);

return this.DWORDS.Max(candidateWords);
}
}

Windows Formuna bir richTextBox ve bir buton ekliyoruz. RichtexBox içindeki kelimeleri parçalayalım. Kelimelerin parçalanacak yerlerini belirlemek için bir dizi oluşturuyorum.
char[] splitChar = new Char[] { ‘ ‘, ‘,’, ‘\n’, ‘.’, ‘?’, ‘!’, ‘\”, ‘’’, ‘:’, ‘;’ };

string[] kelimeler = richTextBox2.Text.Split(splitChar);

//Kelimeler bu noktalardan ayrılacak. kelimeler isimindeki dizimize parçaladığımız kelimeleri atıyoruz.

SpellCorrector Sınıfının bir örneğini oluşturuyoruz.

SpellCorrector den = new SpellCorrector();

küçük isimli değişkeni tanımlama sebebi her kelime için iki kere toLower metodunun programın performansını olumsuz etkileyeceğini düşündüğümden tek metod çalışmasını istedim. richTextBox Find metoduyla yaznlış yazılmış kelimeyi buluyoruz ve altını çizili hale getiriyoruz.

foreach (var item in kelimeler)
            {
                kucuk = item.ToLower();
                if (kucuk!= den.Correct(kucuk))
                {
                    richTextBox2.Find(item);
                    //this.richTextBox1.SelectionBackColor = Color.Yellow;
                    Font currFont = richTextBox2.SelectionFont;
                    Font boldUnderFont = new Font(currFont, FontStyle.Underline);
                    richTextBox2.SelectionFont = boldUnderFont;
                }
            }

Kodumuzun tamamı.

 private void button2_Click(object sender, EventArgs e)
        {
            char[] splitChar = new Char[] { ' ', ',', '\n', '.', '?', '!', '\'', '’', ':', ';' }; 
            SpellCorrector den = new SpellCorrector();
            string[] kelimeler = richTextBox2.Text.Split(splitChar);
            string kucuk;

            foreach (var item in kelimeler)
            {
                kucuk = item.ToLower();
                if (kucuk!= den.Correct(kucuk))
                {
                    richTextBox2.Find(item);
                    //this.richTextBox1.SelectionBackColor = Color.Yellow;
                    Font currFont = richTextBox2.SelectionFont;
                    Font boldUnderFont = new Font(currFont, FontStyle.Underline);
                    richTextBox2.SelectionFont = boldUnderFont;
                }
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            SpellCorrector den = new SpellCorrector();
            textBox4.Text = den.Correct(textBox3.Text);
        }

Ek bir konrol daha ekledim. Yanlış kelimeyi yazıp doğru kelimeyi görmek için. İlk metin kutusuna yazdığınız kelimenin önerisini ikinci metin kutusuna yazıyor. Programın bir sonraki adımında altını çizdiğimiz kelimenin üzerinde sağ tuşa basıldığında kelime önerileri görüntüleyecek ve kelimeyi değiştirecek metodu ekleyeceğim.

1 yorum
  1. YAPTIKLARIM | JN7.net

    […] yazılarımdan birini aldım. C# ta nasıl Yazım kontrolü yapılabileceğini anlatan bir yazı. Yazıyı direk kopyalayıp yeni jn7.net e attım. Yazıyı […]

Cevap bırakın

E-posta hesabınız yayımlanmayacak.