Son günlerde üzerinde çalıştığım bir projede Text Mining ile ilgili daha derin araştırmalar yapmaya ihtiyaç duyuyorum. İngilizcede Stop words elemek çok kolay, çünkü  büyük-küçük harf duyarlığı devre dışı kaldıktan sonra hiç bir programlama dilinde kelimeyi yakalama ihtimaliniz düşmez. Bu Türkçe için böyle değildir. Türkçe karakterler bazı programlama dillerinde özel işlemler gerektirebiliyor. örn php Mutlibyte String eklentisini sunuyor. işlemlerimizi bu kütüphane ile yaptığımız sürece unicode sorunu yaşamıyoruz. mb_string eklentisinin kurulumu için  şurayı ziyaret edebilirsiniz.Multibyte işlemler dışında yine istisnai durumlarımız olabildiği için bu eklentiği kullanmadan regular expression yardımıyla bir filter hazırladım. bu kütüphanemizin de programlanabilmesini sağladı ve tadından yenmez oldu. şimdi bir örnek verelim. Elemek istediğimiz kelime “bir” olsun. büyük-küçük harf duyarlılığını kaldırdığımızda  “BIR” kelimesi de elenecektir. Türkçede bu kelimeler aynı değil! bir ve BİR aynı olabilir ancak. Her kelime için ayrı bir istisna sinsilesi olabileceği için ben de regexpe başvurdum.

Statik Stopwords Datamız:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 class stopWords
    {
        public static $stopwords = array(
        'il[ae]',
        'ke[sş]ke',
        'z?([haeiu][haeiu]?)+',
        'mal',
        'aptal',
        'https?\:\/\/[^\s\"\<]+',
        'B[iİ]r',
        'the',
        'g[o]+l',
        'you',
        '[İi][cç]in',
        'his',
        'ilk',
        'iyi',
        'and',
        '[cç]ok',
        'yok',
        'gibi',
        'ama',
        'ma[çc]',
        'her',
        'var',
        'bizim'
        );
 
        public static function FILTER_STOP_WORDS($word)
        {
            foreach(self::$stopwords as $pattern)
            {
                if(preg_match('/^' . $pattern . '$/i',$word))
                {
                    return false;
                }
            }
            return true;
        }
    }
# 3. elemanımız çok komik her gülmeyi yakaladı, dışında kalan birşey bulamadım (: (örnek : zuahaha zhhhh zihihi hiihi haah eheheh ahehehaeh ) bunların hepsini silebildim.

Elbette liste bununla sınırlı değil siz geliştirip , gruplandırıp desenler arttırabilirsiniz bir metin filtreleme örneği de verelim

0
1
2
3
4
     $text = "Tufan attı ve goooooooooooool hahahaha zuahaha ";
    $words = explode(' ',$text);
    $words = array_filter($words,'stopWords::FILTER_STOP_WORDS');
    $text = implode(' ',$words);
   # cıktı : "Tufan attı"

gol kelimesini ben eledim projemde bilgidğin stop word kategorisine giriyor bu (: siz özelleştirip gelitşirebilirsiinz
iyi çalışmalar,

oracle regexp yeteneklerini kullanarak to_date fonksiyonunda hata verecek tarihleri önceden tespit edip hataya düşmeden null olarak dönmesini sağladık . önce fonksiyonu  vereyim sonrasında bi cümlem daha olacak (:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
CREATE OR REPLACE FUNCTION to_date2(txt IN VARCHAR2,Format IN Varchar2:='DD.MM.YYYY')
   RETURN VARCHAR2
IS
   Gun   INT;
   Ay    INT;
   Yil   INT;
BEGIN
   IF REGEXP_LIKE (
         txt,
         '(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\d\d)'
      )
   THEN
      Gun :=
         TO_NUMBER(REGEXP_REPLACE (
                      txt,
                      '(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\d\d)',
                      '\1'
                   ));
      Ay :=
         TO_NUMBER(REGEXP_REPLACE (
                      txt,
                      '(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\d\d)',
                      '\2'
                   ));
      Yil :=
         TO_NUMBER(REGEXP_REPLACE (
                      txt,
                      '(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\d\d)',
                      '\3'
                   ));
 
      IF MOD (Yil, 4) = 0
      THEN
         IF (Ay = 2 AND Gun > 29)
         THEN
            RETURN NULL;
         END IF;
      ELSIF (Ay = 2 AND Gun > 28)
      THEN
         RETURN NULL;
      END IF;
 
      IF (Ay <= 7)
      THEN
         IF (MOD (Ay, 2) = 1 AND Gun > 31) OR (MOD (Ay, 2) = 0 AND Gun > 30)
         THEN
            RETURN NULL;
         END IF;
      ELSIF (Ay > 7)
      THEN
         IF (MOD (Ay, 2) = 0 AND Gun > 31) OR (MOD (Ay, 2) = 1 AND Gun > 30)
         THEN
            RETURN NULL;
         END IF;
      END IF;
      RETURN TO_CHAR (to_date(Gun||'.'||Ay||'.'Yil),Format);
   END IF;
 
   RETURN NULL;
END;
/

bunlar yerine to_date ve to_char fonksiyonlarını içeren bir fonskiyonla hata yakalandığında null dön diyebilirdik . fonksiyonun tek yaptığı 01/10.2009 gibi farklı işaretler kullanıldığında da ayırabilmek (: ama madem bu kadar uğraştım yayınliim dedim (:

iyi çalışmalar

merhabalar,
  regexp kategorimizi açmışken boş bırakmayalım ilk örneğimiz çok eğlenceli bir parser css parçalicaz. (:

ilk once Css betiğinin yapısını bi görelim

0
1
2
3
4
5
6
7
8
9
10
#eleman{
font-size:11px;
padding:4px;
color:#fff;
}
.elemanlar{
background-color:#fff;
font-size:12px;
padding:4px;
color:#000;
}

ilk once blokları bir birinden ayrımamız lazım yani #eleman1 ve .elemanlar kendi ozelliklerini taşıyorlar her birinin ozellikleri kendisine ozel olacağından bunları birbirinden ayırmamız şart

tek bloğun görüntüsü şu şekilde olur

0
(\.|\#)?([A-Za-z0-9_-]+)(\s)*(\{)?([^\}\{]+)?(})?

şimdi bunları gruplara ayırarak açıklayalım

  1. (\.|\#)  bu elemanda 2 tane işaretçi kullandık biri (.)nokta diğeri (#)sharp  bunları normal bir string olarak kullanacağımızdan başına (\)backslash koyduk arasındaki ((|)cizgi (: )  herhangi biri ile eşleşebilir anlamına geliyor. bunun hemen sonrasına koyduğumuz (?) soru işareti bu katar olmayadabilir anlamında yani 0 ve ya 1 defa bulunabilir anlamındaydı yani 1inci eleman bize null da gelebilir  nokta da gelebilir sharp da gelebilr
    csste nokta gelince class. sharp gelince id boş gelince de bunun tag olduğunu anlıyoruz.
  2. ([A-Za-z0-9_-]+) bu grupta bir karakter seti tanımladık . hazır setlerden faydalandık büyük harf kücük harfler ve 0 dan 9 a tüm rakamlar setler [] içinde tanımlanır ve herhangi biri oluna eşleşme kabul edilir. ] dan sonra koyduğumuz (+)artı  bunların en az 1 tane içermesi gerektiğini belirtir 1den fazla da olabilir.
  3. (\s)  parantez içinde s kullansaydık bize string olarak s yi belirticekti gerçekte string olan  karakterleri işaretçi olarka kullanabilmek için yine başına (\)backslash yazıyoruz. space arıyoruz isimden hemen sonra ama sonunca (*) koyarak olmayadabilir  birden fazla da olabilir diyoruz ve kullanıcı için oraya istediği kadar boşluk atabilme özgürlüğü veriyoruz.
  4. (\{)  hemen sonrasında bir { süslü parantez aradık sonuna da ? koyduk yani ya 1 tane olucak ya da hiç olmayacak.  aslında bu olmak zorunda neden ? koyduk elimize gelen eşleşen[4] içini kontrol edip nullsa kullanıcıyı uyarabilmek için bu kontrolu koyduk. hiç eşleşmemesi de tabi ki kullanıcıyı zorlar bir derleyici gibi düşünelim kendimizi :P cok da şişmeyelim ama :D
  5. ([^\}\{]+) katarı oluşturan 5 inci grubumuz ise cok değişik (: [] set tanımlamak istemişiz ama içinde }{ ve ^var
    başına konulan ^ bu setten birini içermemesi gerektiğini gösterir yani { ve } içermeyen bir set bunun sonuna bir de + koyduk en az 1 karakter içericek. bu grubun da sonuna ? koyduk ya hiç olmicak ya da 1 tane olucak ki zaten burayı sonsuza kadar da yazsanız burası 1 eleman döndürür ta ki siz } veya { koyana kadar. bu eleman boş dönerse bunu yorumlama dışında bırakabiliriz çunku bir property yazılmamıştır. bi de uyarı veririrz:P
  6. (}) bu da en son kapatma elemeanımız bununda yine sonuna ? koyduk ki yokluğunda da bize eşleşme hatası vermesin boş dönsün biz de bunu uyaralım

elemanları birbirinden ayırdık dizimiz 7 eleman olarka dönecektir 1 tanesi eşleşen kısm yani [0] eleman. diğer 6 elemean da yukarda anlattıklarım
şimdi bir de propertyleri ayrımaya geldi sıra

propertyler bize 5 inci elemanda dönüyordu şimdi 5 inci elemanı parse edelim

bize gelen 5 inci elemanın içeriği aşağıdaki gibi olur

0
1
2
3
background-color:#fff;
font-size:12px;
padding:4px;
color:#000;

düzenli ifadesini yazalımn
Pattern:

0
([A-Za-z\-]+)(:)([^;]+)(;)?

bu da color:#fff;  yapısının görüntüsü sonundaki noktali virgul olmasa da olur dedik bazen sonlara konulmuyor şimdi
şimdi burdan da bize 5 eleman dönecek 1 tanesi tamamı  yani [0] eleman

1. eleman property adı : 2 eleman noktalı virgul 3 eleman değeri 4 eleman boş ya da noktalı virgul döner

ve biz de bunları istediğimiz şekilde yorumlar derler kullanırız artık

Testleriniz için Regexper exemi indirebilirsiniz.
http://www.tufyta.com/wp-content/uploads/2009/12/Regexper.zip

c ve türevi diller regexp konusunda çok yeteneklidir. tek başına bir alan olabilecek kapasitede yetenekleri vardır.

action scriptte regexp yeteneklerinden faydalanabilmek için kullanacağımız sınıf da Regexp tir.

r:RegExp=new RegExp("([A-Z])"),
eslesenler:Array=r.exec("bu metin içinden sadece BUYUK HARFLER ayristirilacaktir");

regexp türünde bir r ve Array türünde bir eslesenler  objemiz var.  r objesinin exec() metoduyla verdiğimiz stringi parcalar ve bize  Array olarak döner dönen bu grupları saklayabilmek için eslesenler adında bir dizi tanımladık.

eslesenler dizisine doldurduktan sonra istediğimiz gibi bu diziyi kullanabiliriz.
eslesenler.count eşleşen sayısını eslesenler[0] eslesenler[1] gibi istediğimiz elemana ulaşabilirz.

Örnek Bir Uygulama
http://www.tufyta.com/flexprojects/webregexper/webregexper.html

Kaynak Kodlar :
http://www.tufyta.com/flexprojects/webregexper/srcview/index.html

match yapmadan önce 1 kere logs tabını ziyaret etmelisiniz.

© 2012 Tufan Suffusion theme by Sayontan Sinha