IT & IoT Security | Cloud | It's all about the life itself

Nothing in life is as important as you think it is, while you are thinking about it.

Regular Expression Bölüm 1

Merhaba,

Regular expression, bir arama modelini oluşturan sıralı özel karakterlerdir. Kısaca regex şeklinde ifade edilir.Regex içindeki her karakterin özel bir anlamı vardır.Regex’in yaygın kullanım alanı; bir string,text veya log yığını içinden, istenen arama modeli ile uyuşan kısımların bulunmasını sağlamaktır. Regex’teki özel karakterlere metacharacter(\,?,* gibi) denir.

Regex; 1956’da Kleene’in regular set(küme) ‘i kullanarak regular language’i tanımlaması ile başlamıştır. Anlaşılacağı üzere RegEx’in teorik bir yapısı vardır. 1968’den itibaren regex’in, model uyuşması ve sözcük analizi alanlarında popüleritesi artmıştır. Konunun tarihçesi ve terorik yaklaşımı için kaynaklar kısmında bir kaç adres paylaştım.

Bir kaç regex örneği aşağıdaki gibidir.

^5[1-5]\d{14}$

^35(?:2[89]|[3-8]\d)\d{12}$

^3[47]\d{13}$

Bunlara bakıldığında, muhtelif kredi kartı üreticilerine/kurumlarına ait kredi kartı numaralarını anlattığı düşünülebilir.

Regex’in oluşturulmasını daha rahat anlamak için bazı kavramları ve karakterleri incelemiş olmak yararlı olacaktır. Regex’in teşkil edilmesinde kullanılan özel karakterlere metacharacter dendiğini ifade etmiştim. Metacharacter’lerin genel bir listesi aşağıdaki gibidir.

Metacharacter Description
\ Specifies the next character as either a special character, a literal, a back reference, or an octal escape.
^ Matches the position at the beginning of the input string.
$ Matches the position at the end of the input string.
* Matches the preceding subexpression zero or more times.
+ Matches the preceding subexpression one or more times.
? Matches the preceding subexpression zero or one time.
{n} Matches exactly n times, where n is a non-negative integer.
{n,} Matches at least n times, n is a non-negative integer.
{n,m} Matches at least n and at most m times, where m and n are non-negative integers and n <= m.
. Matches any single character except “n”.
[xyz] A character set. Matches any one of the enclosed characters.
x|y Matches either x or y.
[^xyz] A negative character set. Matches any character not enclosed.
[a-z] A range of characters. Matches any character in the specified range.
[^a-z] A negative range characters. Matches any character not in the specified range.
b Matches a word boundary, that is, the position between a word and a space.
B Matches a nonword boundary. ‘erB’ matches the ‘er’ in “verb” but not the ‘er’ in “never”.
d Matches a digit character.
D Matches a non-digit character.
f Matches a form-feed character.
n Matches a newline character.
r Matches a carriage return character.
s Matches any whitespace character including space, tab, form-feed, etc.
S Matches any non-whitespace character.
t Matches a tab character.
v Matches a vertical tab character.
w Matches any word character including underscore.
W Matches any non-word character.
un Matches n, where n is a Unicode character expressed as four hexadecimal digits. For example, u00A9 matches the copyright symbol
() The ( (open parenthesis) and ) (close parenthesis) may be used to group (or bind) parts of our search expression together
| The | (vertical bar or pipe) is called alternation in techspeak and means find the left hand OR right values, for example, gr(a|e)y will find ‘gray’ or ‘grey’ and has the sense that – having found the literal characters ‘gr’ – if the first test is not valid (a) the second will be tried (e), if the first is valid the second will not be tried. Alternation can be nested within each expression, thus gr((a|e)|i)y will find ‘gray’, ‘grey’ and ‘griy’.
dash(-) The – (dash) inside square brackets is the ‘range separator’ and allows us to define a range, in our example above of [0123456789] we could rewrite it as [0-9].
You can define more than one range inside a list, for example, [0-9A-C] means check for 0 to 9 and A to C (but not a to c).
NOTE: To test for – inside brackets (as a literal) it must come first or last, that is, [-0-9] will test for – and 0 to 9
^ when used inside square brackets The ^ (circumflex or caret) inside square brackets negates the expression
(we will see an alternate use for the circumflex/caret outside square brackets later)
, for example, [^Ff] means anything except upper or lower
case F and [^a-z] means everything except lower case a to z.
^ Matches the beginning of a line
$ Matches the end of the line
. Matches any character
\s Matches whitespace
\S Matches any non-whitespace character
* Repeats a character zero or more times
*? Repeats a character zero or more times (non-greedy)
+ Repeats a character one or more times
+? Repeats a character one or more times (non-greedy)
[aeiou] Matches a single character in the listed set
[^XYZ] Matches a single character not in the listed set
[a-z0-9] The set of characters can include a range
( Indicates where string extraction is to start
) Indicates where string extraction is to end

https://www.py4e.com/lectures/Py4Inf-11-Regex-Guide.pdf

Aşağıdaki kavramları tanımlayalım.

Literal: Arama yaparken veya bir ifadenin uyuştuğu alanları ararken kullanılan gerçek karakterlere “literal” denir. Farklı bir ifade ile, metacharacter olmayan karakterlerdir diyebiliriz. Örneğin merhaba kelimesi içinde geçen aba ‘yı bulmak için kullanılan aba sıralı karakterleri literal string’dir.

Metacharacter: Metacharacter ’ler, arama ifadelerinde(regex,search expression) kullanılan bir veya daha fazla özel anlamı olabilen ve literal olarak kullanılmayan karakterlerdir. Örneğin ^ (caret veya circumflex denmektedir) karakteri metacharacter ‘dir.

Target String: Text veya Log yığını içinde aranıp bulunmak istenen string’dir. Match ve Search Pattern olarak da adlandırabiliriz.

Search Expression: Regex olarak da adlandırılır. Target string’i aramak için kullanılan özel karakterler(metachracter) bütünüdür. Regex’in kendisidir.

Escape Sequence: Escape sequence ile bir metacharacter’i literal olarak kullanacağımızı belirtiyoruz. Belirteç olarak \ metacharacter’i kullanılıyor. Literal olarak kullanılacak olan metacharacter’in önüne \ metacharacteri’ini ekliyoruz.

baris(a) target string’indeki (a) ‘yı bulmak istiyorsak \(a\) regex’ini kullanarabiliriz. \ ile ( ) ‘lerin birer literal string olarak aranacağını ifade etmiş oluyoruz.

Metacharacter’lerin genel bir listesini ve bazı kavramları tanımladık. Regex’i örnekler ile inceleyelim. Örneklerdeki ekran görüntülerinde kutucuklar mevcut(tester). String kutusu, içinde arama yapacağımız text’tir. RE: kutusu, search expression yani regex’tir. Results sonucu göstermektedir. Test araçlarının web adreslerini kaynaklar kısmında paylaştım.

Örnek 1:

ASCII tablosunda kodları belirlenmiş olan karakterleri(rakam,harf,alfa nümerik) aramaya yönelik bir kaç örnek inceleyelim.

String Pattern(regex)
qwe567xcv 567 veya 5\d7 veya 56\d veya \d67
tanim”567″ 567 veya 5\d7 veya 56\d veya \d67
variable t=567; 567 veya 5\d7 veya 56\d veya \d67

Üstteki string’lerde 567 veya 5\d7 veya 56\d veya \d67 regex’leri ile, içinde 567 karakterleri geçen string’leri aramış oluruz. Bu durumda üç string’in üçünde de eşleşme olacaktır.

Aşağıdaki string içinde 789 regex’i ile eşleşen sonuçları elde edebilirsiniz. Üç eşleşme bulunmuştur.

clip_image002

Aşağıda, \d ile yapılan karakter aramaları için aşağıdaki regex’i inceleyebiliriz. 7\d9 regex’ini kullandık.Üstteki eşleşmeyi farklı şekilde elde etmiş olduk.

clip_image004

Bu örnekten anlaşılacağı üzere, \d metacharacter’i, 0-9 arası bir rakam(digit) olarak kullanılmaktadır.

Örnek 2:

.(dot) metacharacter’i joker karakter gibi kullanılıyor. Regex oluştururken .(dot) her hangi bir karakter ile uyuşabilir.

.(dot) metacharacter’ini, literal olarak kullanmak için \ metachracter’ini kullanmak gerekir.

Aşağıdaki örneği inceleyelim.

String Regex
ara. …\.
bjk. …\.
+%6. …\.
rty9 …\.

Dört string mevcut. Kullanılan regex ile şunu elde ettik. String’in ilk üç karakteri her ne olursa olsun, dördüncü karakteri nokta olan kelimeleri(veya modeli) aramış oluyoruz. İlk üç sözcükte eşleşme olacaktır.

Örnek 3:

[ ] – square brackets karakterlerini inceleyelim.

Köşeli parantez içinde kullanılan karakterler , tek tek eşleştirilmeye çalışılır. [123] ; tek bir 1 ile veya 2 ile veya 3 ile eşleştirilebilir.

String Regex
1an [123]an veya [^456]an
2an [123]an veya [^456]an
3an [123]an veya [^456]an
4an [123]an veya [^456]an
5an [123]an veya [^456]an
5an [123]an veya [^456]an

Üstte altı adet string mevcut. İlk üç string ile eşleşecek ve son üç string ile eşleşmeyecek regex’leri düşünelim.

[123]an veya [^456]an regex’leri , ilk üç string ile eşleşir; son üç string ile eşleşemez. [123]an regex’i, ilk karakteri 1veya2veya3 olan,sonraki iki karakteri a ve n olan eşleşmeleri arar. [^456]an regex’i, ilk karakter 4veya5veya6 olmayan, sonraki iki karakteri a ve n olan eşleşmeleri arar. Her ikisi de bu örnekteki amaca uygundur.

^ karakterinin [ ] içindeki kullanımı ile [ ] dışında kullanımı farklı anlamlar içerir!

Benzer bir örnek aşağıdaki gibidir.

clip_image006

[6789] regex’i uyuşan dört eşleşme bulundu. Farklı renk ile taradım.

Örnek 4:

Aşağıdaki örneği, önceki bir kaç örneğin birleşimi olarak ele alabiliriz.

clip_image008

reg[^gu] şeklinde belirlenen regex ile uyuşan kelimeleri sarı ile taradım. Üstteki beş eşleşmenin birini taramayı unutmuşum J

reggu kelimesinde eşleşme olmamasına dikkat ediniz!

clip_image010

Kullandığımız regex ………\. şeklindedir.

Seçtiğimiz regex, ilk dokuz karakteri önemli olmayan onuncu karakteri . (dot literal olarak aranmıştır!) olan sıralı karakterler bütününü ifade etmektedir. Eşleşmeler results kutusunda gösterilmiştir. Toplam beş eşleşme mevcuttur.

Örnek 5:

clip_image012

Bu örnekte seçilen regex ile ilk karakteri b olmayan ikinci ve üçüncü karakteri og olan string’leri aramış oluyoruz.

Üç eşleşme elde ediliyor. Kelimeleri text içine rastgele yerleştirdiğim için text’in anlamı olmayabilir J

Örnek 7:

Dash metacharacter’inin kullanımını inceleyelim. Dash ile bir aralık(range) belirtiliyor. a-z ile a’dan z’ye tüm karakterleri anlatmış oluyoruz. A-Z ile A’dan Z’ye tüm karakterleri ifade etmiş oluyoruz. Büyük küçük harf duyarlılığı mevcuttur! 4-7 ile 4’ten 7’ye kadar olan aralık anlatılmak istenir.

clip_image014

Regex olarak [a-c][7-9] modelini kullandık. Üç eşleşme elde ettik. an8d kelimesinde neden eşleşme olmadığına dikkat ediniz!

Regex’i değiştirelim ve aşağıdaki sonucu inceleyelim.

clip_image016

[a-c]n[7-9] şeklinde seçilen regex ile sadece an8d kelimesi eşleşmektedir. Burada da diğer taradıklarımın neden eşleşmediğine dikkat ediniz!

Örnek 8:

Bir karakterin tekrarlanma sayısı ile ilgili bir örnek yapalım. { } metacharacter’ini kullanarak “tekrar etme” miktarını sorgulayabiliriz. { } karakterleri curly braces olarak adlandırılır.

clip_image018

n{3} regex’i ile üç defa tekrarlanan n karakteri ile eşleşenler aranmış olur. Kullandığım text’te bir eşleşme mevcuttur.

[ karakterinin dört defa kullanıldığı eşleşmelere bakalım. Örnek text ve regex aşağıdaki gibidir.

clip_image020

Kullandığımız regex \[{4} şeklindedir. \ metacharacter’inin kullanımına dikkat ediniz. \ ile [ karakterini literal olarak kullandık.

R{2,7} regex’i ile, içinde en az iki, en fazla yedi defa R karakteri geçen eşleşmeleri arayabiliriz.

E{3,} regex’i ile, içinde en az üç defa veya daha fazla bilinmeyen sayıda E karakteri geçen eşleşmeleri arayabilirsiniz.

Örnek 9:

Şu ana kadar incelediğimiz metacharacter’ler ile gerçek hayat senaryosuna daha yakın bir örnek yapabiliriz.

Event yığınları arasında veya text içinde, aşağıdaki pattern ile eşleşenleri bulmaya çalışalım. Eşleşmeleri DLP sistemi için kullanacağınızı varsayabilirsiniz.

String : 4443-9999-yyy

String’de, son y ‘den sonra gelen herhangi bir karakteri(boşluk,numeric,digit,alfa numeric olabilir) de göz önüne alalım. Yani toplamda 14 karakterin eşleşmesini göz önüne almış olacağız.

clip_image022

4{3}\d\-9{4}\-y{3}\d. şeklinde bir regex kullanabiliriz. Dört eşleşme elde edildi. Regex’i incelersek;

– Ard ard üç defa 4 karakterini

– Sonrasinda her hangi bir digit’i

– Sonrasında dash karakterini

– Sonrasında ard ard dört defa 9 karakterini

– Sonrasında dash karakterini

– Sonrasında ard arda üç defa y karakterini

– Sonrasında herhangi bir digit’i

– Sonrasında herhangi bir karakteri içeren sözcük veya eşleşme

Üstte bahsedilen kriterlere uygun karakterler bütününü eşleştirmiş olduk.

Örnek 10:

Kleene Star ve Kleene Plus olarak geçen * ve + metacharacter’lerinin kullanımını içeren bir kaç örnek inceleyelim.

Bga* regex’i ile eşleşen string’ler, Bgaaarty(a üç defa eşleşir), Bgaa(a iki defa eşleşir), Bg1thy(a sıfır defa eşleşir!) şeklinde olabilir.

Bga+ regexi’i ile eşleşen string’ler, Bgaaarty(a üç defa eşleşir), Bgaa(a iki defe eşleşir) fakat Bg1thy string’inde bir eşleşme olmaz.

Üstteki örneklere göre şu şekilde tanımlayabiliriz. * metacharacter’i , bir önceki karakterin sıfır veya daha fazla sayıda eşleşmesini araştırır. + metacharacter’i, bir önceki karakterin bir veya daha fazla sayıda eşleşmesini araştırır.

clip_image024

Üstte, 20* regex’i ile string içinden altı eşleşme elde edilmektedir. 2443 string’inde,Kleene Star’ının ,yani * metacharacter’inin, eşleşmeyi yakaladığına dikkat ediniz!(olması gerektiği gibi)

clip_image026

Üstteki örnekte 20+ regex’ini kullandık. String içinde beş eşleşme elde edildi. 2443 karakterler bütününün eşleştirilmediğine dikkat ediniz! Eşleştirme için 0 karakterinin, string içinde en az bir defa geçmiş olması gerekiyordu.

Benzer bir örnek aşağıdaki gibidir.

ttttbcc , ttbbbbc , ttcc string’lerinin her üçü için ; t{2,4}b{0,4}c{1,2} şeklinde bir regex ile veya t+b*c+ şeklinde bir regex ile eşleştirme sağlayabiliriz.

Kleene Star ile Kleen Plus metacharacter’lerinin kullanımını incelemiş olduk.

Örnek 11:

? metacharacter’ini inceleyelim. * veya + metacharacter’lerinden farklı olarak sıfır veya bir defa varolma durumunu eşleştirir.

clip_image028

co?de regex’ini kullandığımızda üstteki string’de üç eşleşme elde edilmektedir. coode sözcüğü bu eşleşmelerden biri değildir. Çünkü iki adet o karakteri içermektedir.

Regex olarak co*de kullanıldığında,

clip_image030

dört eşleşme elde edilir.

Regex olarak co+de kullanıldığında,

clip_image032

iki eşleşme elde edilir.

Bu örnek ile * + ve ? metacharacter’leri arasındaki farkları incelemiş olduk.

Örnek 12:

Boşluk(space,whitespace) karakterini inceleyelim.

\s metacharacter’i her türlü boşluk için kullanılabilir. Farklı türde(tab,satırbaşı gibi) boşluklar için \r \t \n metacharacter’leri de kullanılabilir.

clip_image034

Üstteki string’de \+\s*[r-u][g-j] regex’ini kullandım. Bir eşleşme elde edildi.

Eşleşmeyi irdelediğimizde,

– + karakteri ile başlayan

– + karakterinden sonra sıfır veya daha fazla sayıda boşluk içeren

– r,s,t,u aralığında bir karakter içeren

– g,h,i,j aralığında bir karakter içeren sözcükleri veya sıralı karakterler bütününü elde

etmiş oluyoruz.

Satırbaşındaki boşluk için spesifik olarak \n metacharacter’i kullanılabilir.

clip_image036

\n\s+w regex’i ile satır başında bir veya daha fazla sayıda boşluk içeren, boşluktan sonraki ilk karakteri w olan eşleşmeler elde edilir.

Regex’i aşağıdaki şekilde değiştirelim ve sonucu görelim.

clip_image038

\n\s*w regex’i ile iki eşleşme elde edilmektedir. * ile + arasında farka dikkat ediniz!

Yazımda, regex’i teşkil etmek için kullanabileceğimiz metacharacter’lerden bazılarını, örnekler ile inceledik. Sonraki yazımda regex’ler için farklı örneklere devam edeceğim.

Herkese sorunsuz ve neşeli günler dilerim.

Kaynaklar:

http://www.cs.rit.edu/~rwd/CS_Theory/pdf/0201-RegularExpressions.pdf

http://www.cs.princeton.edu/courses/archive/spr05/cos126/lectures/18.pdf

https://courses.engr.illinois.edu/cs373/fa2010/lectures/lect06.pdf

http://regexone.com/

http://www.zytrax.com/tech/web/regex.htm#more

https://www.hscripts.com/tutorials/regular-expression/metacharacter-list.php

http://en.wikipedia.org/wiki/ASCII#ASCII_printable_characters

http://www.cs.uky.edu/~lewis/texts/theory/automata/reg-sets.pdf

http://blog.staffannoteberg.com/2013/01/30/regular-expressions-a-brief-history/

https://www.regex101.com/

http://www.richardsramblings.com/regex/credit-card-numbers/

12 comments found

  1. Eline sağlık,

    Gerçekten bizim gibi özellikle olay yönetimi ile ilgilenen kişiler için çok faydalı bir yazı olmuş.
    Regex kullanımını bu kadar iyi anlatan değil Türkçe İngilizce yazı bulmak bile zor. Çok teşekkürler
    Devamını bekliyoruz…

  2. Eline sağlık,

    Gerçekten bizim gibi özellikle olay yönetimi ile ilgilenen kişiler için çok faydalı bir yazı olmuş.
    Regex kullanımını bu kadar iyi anlatan değil Türkçe İngilizce yazı bulmak bile zor. Çok teşekkürler
    Devamını bekliyoruz…

  3. Detaylı inceleme için çok teşekkürler.

    örnek 10 ‘da, belirtilen eşleşmenin 5 olması gerekmiyor mu?

    “Üstteki örnekte 20+ regex’ini kullandık. String içinde dört eşleşme elde edildi.”

  4. Detaylı inceleme için çok teşekkürler.

    örnek 10 ‘da, belirtilen eşleşmenin 5 olması gerekmiyor mu?

    “Üstteki örnekte 20+ regex’ini kullandık. String içinde dört eşleşme elde edildi.”

    1. Değerli yorumunuz için teşekkür ederim. Results kısmında “5” eşleşme olduğu görülüyor. Altındaki kısımdaki paragrafa yazarken “4” yazmışım. Düzeltme için teşekkür ederim.

Comments are closed.