24 Mayıs 2013 Cuma

Düzenli İfadeler (Regular Expressions) ve Programlama Dilleri

Düzenli ifadeler bana her zaman çok karışık gelmiştir. Aşağıda bazı notlarım var.

Tamamen Eşleşme
boost
boost::regex_match ile verilen string'in tamamının düzenli ifadeyle uyuşup uyuşmadığı kontrol edilir. Aşağıda bu durum açıklanmış.

Örnek
#include <boost/regex.hpp>
boost::regex e ("my pattern");
if ( regex_match ("toFind", e ) )
{
    //Yes...
}
Java
String.matches(String regex) ile eşleşme kontrol edilir.

Tamamen Eşleşme ve Yakalama
boost match_result sınıfının first() ve second() metodları ile iterator kullanma
Bir diğer örnek ise tamamen eşleşme ve verilen string içindeki alanların yakalanması. Örneği boost'un kendi sayfasından aldım.Yakalama için match_result sınıfı kullanılır.Bu sınıfın first ve second metodları ile yakalanan string'e işaret eden iterator'lere erişilebilir.


Arzu edilirse eşleşen alanlar üzerinde döngüyle de dolaşılabilir. Döngünün 1'den başladığına dikkat etmek lazım.

Yakalamak için boost içinde boost::smatch what veya boost::cmatch what gibi iki farklı yapının kullanıldığını gördüm ama aralarındaki fark nedir bilmiyorum.

boost match_result sınıfının prefix() ve suffix() metodlarını kullanma
Aşağıdaki örnekte eşleşme yapılan grubun ön ve sonundaki stringleri alabilme imkanı var.



boost match_result sınıfının str() metodunu kullanma
Yukarıdaki örnekte eşleşmeyi bir string içine almak için first(), second() metodlarını kullandık. Aşağıdaki örnekte ise eşleşmeyi direkt string olarak almak için str() metodunu kullanıyoruz.
 
Java
Aşağıda ilginç bir örnek gördüm. Yakalama grubuna $1 ile erişmiş.

 
Kısmi Eşleşme
C++
C++ 11 regex: checking if string starts with regex sorusunda da gösterildiği gibi regex_search ile yapılır.
std::regex_constants::match_continuous bayrağı verilen string'in düzenli ifade ile başlaması gerektiğini belirtir.

boost regex_search (İlk eşleşme)
regex_search ile yapılır. Bu metod ile match_result sınıfı aracılığıyla eşleşme yapılan string'i alabilme imkanı vardır. İstenmezse sadece metodun döndürdüğü değere de bakılabilir.

Burada dikkat edilmesi gereken nokta smatch veya cmatch yapısı regex_search sınıfına geçilen string'e pointer tutuyorlar. Eğer C++ regex string capture sorusundaki gibi metoda temporary string geçersek hata yapmış oluruz.
smatch sm1;
regex_search(string("abhelloworld.jpg"), sm1, regex("(.*)jpg"));//hata...
cout << sm1[1] << endl;
Java
Buradaki soruda açıklandığı gibi string içindeki tüm sayıları almak için aşağıdaki örnek kullanılabilir.group() metodu ile eşleşmeyi sağlayan tüm string alınabilir.
Bir diğer örnekte ise WWW ile başlayıp : ile biten patern yakalanıyor.


Kısmi Eşleşme ve Yakalama
boost sregex_iterator - Yakalama Grubuna Sayı ile Erişme
sregex_iterator iterator sınıfı ile verilen string üzerinde döngü kurmak çok kolay. How do I loop through results from std::regex_search? sorusunda açıklandığı gibi tüm kısmi eşleşmeleri almak için aşağıdaki gibi bir kod lazım.

Java - Yakalama Grubuna Sayı ile Erişme
Aşağıdaki örnekte kısmi eşleşme sağlayan tüm parçalar döngü içinde alınabilir. Aşağıda group(1) metodunun çağırılmasının sebebi group(int) metodunda şöyle açıklanmış.
Capturing groups are indexed from left to right, starting at one. Group zero denotes the entire pattern, so the expression m.group(0) is equivalent to m.group(). 
Eğer capturing gruplama yapılmıyorsa Matcher sınıfının start() ve end() metodları kullanılabilir.
Pattern p = Pattern.compile("[A-Z]+");
Matcher m = p.matcher(data);
List<String> sequences = new ArrayList<String>();
while (m.find()) {
    sequences.add(data.substring(m.start(), m.end()));
}

Case Insensitive Çalışma
boost
  boost::regex regex ("your epxression here",boost::regex::icase);
C#
Regex r = new Regex(@"your epxression here", RegexOptions.IgnoreCase);
Java
Java ile case insensitive çalışma için düzenli ifadeye (?i) karakterini eklemek lazım. Örnek:
Ancak bu seçenek sadece ASCII kodları için çalışıyor. Eğer Unicode karakterler de bulunsun isteniyorsa (?ui) karakterlerini kullanmak lazım.
Tüm Eşleşmeleri Alma
C#
Regex sınıfı yazısına taşıdım.

Java
C#'taki kadar kolay olmasa da yukarıdaki örneklerde görüldüğü gibi döngü ile dönerek tüm eşleşmeleri alma işlemi yapılabiliyor. Matcher sınıfının find metodu kullanılırken metodun çalışma şekline dikkat etmek lazım. Açıklamadan da görüldüğü gibi Matcher sınıfı bir önceki aramada nerede kaldığını hatırlıyor.

  
Birden Fazla Satır İle Çalışma
Java
Eşleşen İfadeyi Başka Bir String İle Değiştirme 
C++ 
regex_replace ile yapılır.
regex rx("world.*");
regex_replace("hello world hello", rx, "myworld");//çıktı olarak hello myworld verir

 

Hiç yorum yok:

Yorum Gönder