Skip to content

Pratik bir Türkçe heceleme çözümü

License

Notifications You must be signed in to change notification settings

alperali/hecele

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

(This content is also available in English)

Türkçe Heceleme

Bu proje, sözlük veri tabanı gerektirmeyen, algoritmik bir heceleme yönteminin anlatımı ve uygulamasıdır.1

Demo animasyonu

Demo için güncel bir Chrome, Edge, Firefox, vs sürümü kullanın.

Kendi girdiğiniz metinin hecelenişini görmek içindir. Bir sözcük veya kısa metin girip Heceleye tıklayın. Tireleri silmek için Geri alı tıklayın.

Bulduğunuz hataları alper.goplay@gmail.com adresine bildirin, veya Issues altında bir kayıt açın.


Giriş

Basit ve yalın bir morfolojik yapısı olan Türkçede heceleme (hyphenation) Hint-Avrupa dillerindekinden farklıdır. Bitişken (agglutinative) bir dil olan Türkçede teorik olarak sözcük uzunluğunun bir üst sınırının olmaması, sözlük veri tabanı kullanımını (dictionary lookup) anlamsız kılar. O dillere göre tasarlanmış yazılım ve/veya kütüphanelere Türkçeyi eklemeye çalışmak yerine özgün ve rasyonel bir yaklaşım mümkündür. Türkçe heceleme deterministiktir, sade ve açık kurallar ile formüle edilebilir.

Bulgular

Türkçe üzerine birinci bulgu:

Türkçe sözcükteki bir hecenin yeri, kendinden önce gelen hecelerden bağımsızdır.

Bu çok iddialı gibi görünen bulguyu açıklayan bir örnek verelim:

sözcük hecelenişi
arkadaşlarından ar-ka-daş-la-rın-dan

Şimdi bu sözcüğün sadece ilk hecesini bulalım, sonra o heceyi sözcükten ayıralım:

ilk hece kalanı
ar-kadaşlarından kadaşlarından

Geriye kalan kadaşlarından anlamlı bir Türkçe sözcük değil, ancak hecelenmesine engel bir durum yok. İlkokul 1. sınıf bilgimizi kullanarak bu sözcük parçasının ilk hecesini bulalım, sonra gene bu heceyi ayıralım:

ilk hece kalanı
ka-daşlarından daşlarından

Görüldüğü üzere ka- hecesini, öncesinde ar- olup olmadığını hesaba katmadan doğru olarak bulabiliyoruz. İşte bir hece yerinin, önceki hecelerden bağımsızlığı ilkesi budur.
Sözcük parçasının sonuna ulaşana kadar işleme devam edelim:

ilk hece kalanı
daş-larından larından
la-rından rından
rın-dan dan
dan -

Bu aşamada Türkçe üzerine ikinci bir bulguyu belirtelim:

Türkçede henüz bilinmeyen, icat edilmemiş sözcüklerin bile nasıl heceleneceği bellidir.

Çözümün algoritmik çatısı şöyledir: Sözcükte ilk heceyi bul, bunu ayır, kalanı yeni bir sözcükmüş gibi ele al, ilk hecesini bul, bunu ayır, kalanı yeni bir sözcükmüş gibi... ta ki sözcük bitene kadar. Bu tipik bir özyinelemeli (recursive) algoritmadır. Bu aşamada problemi “bir sözcüğün (veya sözcük parçasının) ilk hecesinin bulunması”na indirgemiş olduk. Sonraki bölümde bunu ele alacağız.

İlk Hece Kuralları

Bu bölümde bir sözcük (veya sözcük parçasının) ilk hecesini bulan kurallar belirtilmektedir. Kurallara sırayla bakılacak ve uyan ilk kural heceyi bulmuş kabul edilecek, sonraki kurallara bakılmayacaktır. Her kuralda sözel anlatımı takiben örnekler, simgesel gösterim ve heceyi saptayan bir RegEx örüntü (pattern) verilmiştir.2 Sözel anlatımda geçen “sözcük” terimi “sözcük veya sözcük parçası” anlamındadır. Simgesel gösterimde N ünlü, z ünsüzü temsil eder. Kolaylık sağlaması için sözcükte noktalama imleri ve rakamlar olmadığı varsayılmıştır.

  1. Sözcük 3 harften kısa ise ilk hece sözcüğün tamamıdır.

    ev
    şu
    il
    at
    -
    -
  2. Sözcük ünlü-ünsüz-ünlü olarak başlıyorsa ilk hece 1 harftir.

    ö-de-me
    i-liş-kin
    e-mir
    a-ra
    NzN :1
    /^[aeiouöüıİ][bcçdfgğhjklmnprsştvyz][aeiouöüıİ]/i
  3. Sözcük ünlü-ünlü-ünsüz olarak başlıyorsa ilk hece 1 harftir.

    a-i-le
    a-it
    a-i-di-yet
    i-a-şe
    i-a-ne
    NNz :1
    /^[aeiouöüıİ]{2}[bcçdfgğhjklmnprsştvyz]/i
  4. Sözcük ünsüz-ünlü-ünlü olarak başlıyorsa ilk hece 2 harftir.

    sa-at-ler
    fi-il
    ka-i-de
    me-sa-i
    zNN :2
    /^[bcçdfgğhjklmnprsştvyz][aeiouöüıİ]{2}/i
  5. Sözcük ünlü-ünsüz-ünsüz-ünlü olarak başlıyorsa ilk hece 2 harftir.

    em-ri-ne
    iş-le-min
    ak-tar-ma
    NzzN :2
    /^[aeiouöüıİ][bcçdfgğhjklmnprsştvyz]{2}[aeiouöüıİ]/i
  6. Sözcük ünsüz-ünlü-ünsüz-ünlü olarak başlıyorsa ilk hece 2 harftir.

    ve-rir
    ta-li-mat
    ma-hi-ye-ti-ne
    zNzN :2
    /^([bcçdfgğhjklmnprsştvyz][aeiouöüıİ]){2}/i
  7. Sözcük ünlü-ünsüz-ünsüz-ünsüz olarak başlıyorsa ilk hece 3 harftir.
    Sözcük ünlü-ünsüz-ünsüz olarak tam 3 harf ise ilk hece sözcüğün tamamıdır.

    ilk-ba-har
    üst-te-ki
    alt-lık
    ilk
    alt
    üst
    Nzzz :3
    Nzz. :3
    /^[aeiouöüıİ][bcçdfgğhjklmnprsştvyz]{2}($|[bcçdfgğhjklmnprsştvyz])/i
  8. Sözcük ünsüz-ünlü-ünsüz-ünsüz-ünlü olarak başlıyorsa ilk hece 3 harftir.
    Sözcük ünsüz-ünlü-ünsüz olarak tam 3 harf ise ilk hece sözcüğün tamamıdır.

    bil-gi
    müş-te-ri
    sağ-lam
    son
    kal
    gel
    zNzzN :3
    zNz. :3
    /^[bcçdfgğhjklmnprsştvyz][aeiouöüıİ][bcçdfgğhjklmnprsştvyz]($|[bcçdfgğhjklmnprsştvyz][aeiouöüıİ])/i
  9. Sözcük ünsüz-ünsüz-ünlü-ünsüz-ünlü olarak başlıyorsa ilk hece 3 harftir.

    pro-je
    kra-li-çe
    tra-fo
    pro-fes-yo-nel
    zzNzN :3
    /^[bcçdfgğhjklmnprsştvyz]{2}[aeiouöüıİ][bcçdfgğhjklmnprsştvyz][aeiouöüıİ]/i
  10. Sözcük ünsüz-ünlü-ünsüz-ünsüz-ünsüz olarak başlıyorsa ilk hece 4 harftir.
    Sözcük ünsüz-ünlü-ünsüz-ünsüz olarak tam 4 harf ise ilk hece sözcüğün tamamıdır.

    borç-lan-mak
    fark-lı-laş-tır
    kont-rol
    kang-ren
    mert
    hurç
    Türk
    sant-ral
    zNzzz :4
    zNzz. :4
    /^[bcçdfgğhjklmnprsştvyz][aeiouöüıİ][bcçdfgğhjklmnprsştvyz]{2}($|[bcçdfgğhjklmnprsştvyz])/i
  11. Sözcük ünsüz-ünsüz-ünlü-ünsüz-ünsüz-ünlü olarak başlıyorsa ilk hece 4 harftir.
    Sözcük ünsüz-ünsüz-ünlü-ünsüz olarak tam 4 harf ise ilk hece sözcüğün tamamıdır.

    prog-ram-cı
    Trak-ya
    spor
    tren
    zzNzzN :4
    zzNz. :4
    /^[bcçdfgğhjklmnprsştvyz]{2}[aeiouöüıİ][bcçdfgğhjklmnprsştvyz]($|[bcçdfgğhjklmnprsştvyz][aeiouöüıİ])/i
  12. Sözcük ünsüz-ünsüz-ünlü-ünsüz-ünsüz-ünsüz olarak başlıyorsa ilk hece 5 harftir.
    Sözcük ünsüz-ünsüz-ünlü-ünsüz-ünsüz olarak tam 5 harf ise ilk hece sözcüğün tamamıdır.

    prens
    trend
    trans
    prens-ler
    trans-for-mas-yon
    sport-men-ce
    trans-krip-si-yon
    zzNzzz :5
    zzNzz. :5
    /^[bcçdfgğhjklmnprsştvyz]{2}[aeiouöüıİ][bcçdfgğhjklmnprsştvyz]{2}($|[bcçdfgğhjklmnprsştvyz])/i

Kullanım ve Uygulama

Bu çalışma standart web teknolojilerini baz almaktadır (gerekirse şirkete/markaya özel teknolojilere uyarlanabilir). Bu bağlamda CSS hyphens property odaklı bir uygulama yapılmıştır.3 Elektronik belgelerin düzgün gösterimi (satır sonu doğru yerde bölme) için tire olarak U+00AD (gizli tire / soft hyphen), tüm hecelerin açıkça gösterimi için tire olarak U+2010 (açık tire / hard hyphen) kullanılmaktadır. Yukarıda bahsedilen 12 kurala göre heceleme yapan ve tire türünü (gizli veya açık) argüman olarak alabilen örnek bir Javascript modülü aşağıda gösterilmiştir.

const SHY = '\u00AD';  // gizli tire (soft hyphen)
const HRD = '\u2010';  // açık tire  (hard hyphen)
const kurallar = [
  { ptn: /^[aeiouöüıİ][bcçdfgğhjklmnprsştvyz][aeiouöüıİ]/i,    len: 1}, // 2.
  { ptn: /^[aeiouöüıİ]{2}[bcçdfgğhjklmnprsştvyz]/i,            len: 1}, // 3.
  { ptn: /^[bcçdfgğhjklmnprsştvyz][aeiouöüıİ]{2}/i,            len: 2}, // 4.
  { ptn: /^[aeiouöüıİ][bcçdfgğhjklmnprsştvyz]{2}[aeiouöüıİ]/i, len: 2}, // 5.
  { ptn: /^([bcçdfgğhjklmnprsştvyz][aeiouöüıİ]){2}/i,          len: 2}, // 6.
  { ptn: /^[aeiouöüıİ][bcçdfgğhjklmnprsştvyz]{2}($|[bcçdfgğhjklmnprsştvyz])/i, len: 3},        // 7.
  { ptn: /^[bcçdfgğhjklmnprsştvyz][aeiouöüıİ][bcçdfgğhjklmnprsştvyz]($|[bcçdfgğhjklmnprsştvyz][aeiouöüıİ])/i, len: 3},    // 8.
  { ptn: /^[bcçdfgğhjklmnprsştvyz]{2}[aeiouöüıİ][bcçdfgğhjklmnprsştvyz][aeiouöüıİ]/i, len: 3}, // 9.
  { ptn: /^[bcçdfgğhjklmnprsştvyz][aeiouöüıİ][bcçdfgğhjklmnprsştvyz]{2}($|[bcçdfgğhjklmnprsştvyz])/i, len: 4},            // 10.
  { ptn: /^[bcçdfgğhjklmnprsştvyz]{2}[aeiouöüıİ][bcçdfgğhjklmnprsştvyz]($|[bcçdfgğhjklmnprsştvyz][aeiouöüıİ])/i, len: 4}, // 11.
  { ptn: /^[bcçdfgğhjklmnprsştvyz]{2}[aeiouöüıİ][bcçdfgğhjklmnprsştvyz]{2}($|[bcçdfgğhjklmnprsştvyz])/i, len: 5}          // 12.
];

function hecele(szck, tire = SHY)
{
  if (szck.length < 3)        // 1.
    return szck;

  for (const kural of kurallar)
    if (kural.ptn.test(szck))
      if (szck.length > kural.len)
        return `${szck.slice(0, kural.len)}${tire}${hecele(szck.slice(kural.len), tire)}`;
      else
        return szck;
    
  return szck;   // hiçbiri uymadı, aynen döndür.
}

Object.defineProperty(hecele, 'SHY', { value: SHY});
Object.defineProperty(hecele, 'HRD', { value: HRD});

export default hecele;

Belge üzerinde kullanım

Heceleme modülü noktalama imleri içermeyen tek sözcük üzerinde çalışmaktadır. Tüm bir belgenin bu modülden fayda sağlaması için noktalama imleri atlanarak sözcükler sırayla bu modüle gönderilmeli, tireler yerleştirilmiş sözcükler noktalama imlerini kaybetmeden ve orjinal sırasında belge içerisine geri konulmalıdır (veya yeni bir belge oluşturulmalıdır). Bu işlemi gösteren örnek bir Javascript bloğu şöyle olabilir:

const nokim = /([\s\u00AD\u2010,;:.'"’“”!?\/()-]+)/;  /* noktalama imleri örüntüsü */
belge.split(nokim)
     .map((e) => {
        if (nokim.test(e)) return e;
        return hecele(e, hecele.SHY);
      })
     .join("");

13. kural

Ayırmada satır sonunda ve satır başında tek harf bırakılmaz4

Bu duruma uyan harfler 2, 3 ve 4. kurallarda gözlenir, örneğin ö-deme, a-ile, mesa-i. Her üç durumda da tek kalan harf bir ünlüdür. Bu kuralı uygulamak için hecelenmiş sözcüğün ilk ve son tirelerine bakılır, öncesinde veya sonrasında tek bir ünlü varsa bu tire kaldırılır, böylece satır sonunda ayırma engellenir.

const nokim = /([\s\u00AD\u2010,;:.'"’“”!?\/()-]+)/;  /* noktalama imleri örüntüsü */
const k13 = /^([aeiouöüıİ])[\u00AD\u2010]|[\u00AD\u2010]([aeiouöüıİ])$/gi;  // 13.
belge.split(nokim)
     .map((e) => {
        if (nokim.test(e)) return e;
        return hecele(e, hecele.SHY).replace(k13, '$1$2');
      })
     .join("");

Özel Durumlar

Buraya kadar anlatılan çözüm, bazı yabancı kökenli sözcükler ve yabancı kökenli sözcüklerin bulunduğu bazı birleşik sözcüklerde doğru çalışmamaktadır (Vanspor, Demirspor, şokokrem, popstar, elektrik, vs). Bu durumları kapsayacak şekilde çözümü revize etmek harf analizinden çıkıp sözcük analizine yönelmeye sebep olacağından algoritmayı karmaşıklaştırır. Ana yoldan çıkmadan bir kısayol (kestirme) çözüme entegre edilebilir. Böyle sözcüklerde bir kılavuz nokta tespit edip iki farklı sözcük varmış gibi hecelemeye başlamak sorunu ortadan kaldırmaktadır (Van·spor, Demir·spor, şoko·krem, elek·tronik, vs). ➡️

Borçlanma, gençlik, somurtkan, farklılık gibi sözcüklerin hecelenmesini sağlayan 10. kural kontrol, santral, kangren gibi batı kökenli bazı sözcüklere de uyup hatalı hecelenmelerine sebep olmaktadır. Böyle sözcükler bu listeye eklenip doğru hecelenmeleri sağlanabilir.

Footnotes

  1. Bu anlatım 2016’da yapılmış bir çalışmaya dayanmaktadır.

  2. Örüntüler standart Javascript RegEx nesnesini baz alır. Sistem locale ayarlarına göre değişkenlik gösterdiği için character class ve range kullanımı tercih edilmemiştir.

  3. https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens

  4. https://www.tdk.gov.tr/icerik/yazim-kurallari/hece-yapisi-ve-satir-sonunda-kelimelerin-bolunmesi/

About

Pratik bir Türkçe heceleme çözümü

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published