# Desenler

- **İngilizce aslı:** https://wiki.facepunch.com/gmod/Patterns
- **Çeviri tarihi:** 2025-09-08

### Bu makale ne için?

Bu makale, Lua'nın kalıp eşleştirme dilini nasıl kullanacağınızı öğretmek içindir. Kalıp eşleştirme dili (veya kısaca `kalıplar`), metinlerde tekrar eden kalıpları aramak ve değiştirmek için gelişmiş araçlar sunar. Bu araçlar, metin verisi ayrıştırıcıları, özel biçimlendiriciler ve normalde yüzlerce satır kod gerektirecek diğer birçok şeyi yazmak için kullanılabilir.

Bu makaledeki teorinin büyük bir kısmı Lua referans kılavuzundan kopyalanmış veya yeniden yazılmıştır. Kılavuzun kalıplarla ilgili bölümünü [burada](http://www.lua.org/manual/5.2/manual.html#6.4.1) görebilirsiniz.

### Başlarken

Ortalama bir kalıp şuna benzer:

```lua
[%w_]+
```

Bu özel kalıp, değişken adlarını (örneğin "hi_there", "h0w_are_you" vb.) bulmak için kullanılabilir. Kalıptaki her bir karakterin ne işe yaradığı bu makalenin ilerleyen kısımlarında açıklanacaktır.

Bu fonksiyonlar kalıplarla birlikte kullanılabilir:

- [string.find](https://gmod.tr/wiki/string.find)
- [string.match](https://gmod.tr/wiki/string.match)
- [string.gmatch](https://gmod.tr/wiki/string.gmatch)
- [string.gsub](https://gmod.tr/wiki/string.gsub)
- [string.Explode](https://gmod.tr/wiki/string.Explode)

Bu fonksiyonların hepsini kullanmaya ve her birinin nasıl çalıştığını ayrıntılı olarak açıklamaya çalışacağım.

Kalıpları öğrenirken ve pratik yaparken yardımcı olarak [bu](https://gitspartv.github.io/lua-patterns) web sitesini kullanın.

### Özel karakterler

Diğer karakterleri kaçış karakteri olarak belirleyen (escape) veya kalıbı bir şekilde değiştiren bir dizi özel karakter vardır.

Bu karakterler şunlardır:

```lua
^ $ ( ) % . [ ] * + - ?
```

Bunlar ayrıca, önlerine bir "%" karakteri eklenerek kalıpta normal karakterler olarak da kullanılabilirler, böylece "%%", "%" olur, "%[", "[" olur, vb.

### Karakter sınıfları

Karakter sınıfları bir karakter kümesini temsil eder. Bunlar, önceden tanımlanmış kümeler veya aynı önceden tanımlanmış kümelerden, aralıklardan veya herhangi bir tek karakterden oluşabilen özel kümeler olabilir.

Mevcut karakter sınıfları (özel ve önceden tanımlanmış):

| Sınıf | Açıklama |
|---|---|
| `%a` | tüm harfleri temsil eder (a'dan z'ye büyük ve küçük harf) |
| `%c` | tüm kontrol karakterlerini temsil eder (özel karakterler "\t", "\n", vb.) |
| `%d` | tüm rakamları temsil eder (0'dan 9'a kadar) |
| `%g` | boşluk hariç tüm yazdırılabilir karakterleri temsil eder ('[\x21-\x7E]' ile aynı) |
| `%l` | tüm küçük harfleri temsil eder (küçük harf olan herhangi bir harf) |
| `%p` | tüm noktalama işaretlerini temsil eder (".", ",", vb.) |
| `%s` | tüm boşluk karakterlerini temsil eder (normal boşluk, sekme, vb.) |
| `%u` | tüm büyük harfleri temsil eder (büyük harf olan herhangi bir harf) |
| `%w` | tüm alfanümerik karakterleri temsil eder (tüm harfler ve sayılar) |
| `%x` | tüm onaltılık (hexadecimal) basamakları temsil eder (0-9 arası rakamlar, a-f arası harfler ve A-F arası harfler) |
| `%z` | 0 temsiline sahip karakteri temsil eder (null karakteri "\0") |
| `%char` | herhangi bir sınıfı temsil etmiyorsa bir karakteri kaçış karakteri olarak belirler (ör. '%[(%d)%]' parantez içindeki bir rakamla eşleşir) |
| `[set]` | 'set' içindeki tüm karakterleri bir birleşim olarak temsil eder. Bunun önceki bölümde kullanıldığını görebilirsiniz. '[%w_]' herhangi bir harf, rakam ve alt çizgi ile eşleşir |
| `[^set]` | 'set' birleşiminin tersini temsil eder, yani '[^%w_]' bir harf, rakam veya alt çizgi olmayan her şeyle eşleşir |

- Önceden tanımlanmış bir karakter kümesinin büyük harfli versiyonu, o kümenin **tersini** temsil eder, yani `%A` bir harf **olmayan** her şeyle eşleşir,
- Bir aralığın başlangıç ve bitiş noktaları bir kısa çizgi "-" ile ayrılır, yani `0-5` sıfırdan beşe kadar bir rakamla eşleşir, `a-c` a, b veya c ile eşleşir.

#### Tekrarlama ve Sabitleme

Bir metindeki karakterler bir kalıpla aşağıdaki şekillerde eşleşir:

- tek bir sınıf tek bir karakterle eşleşir,
- "+" ile takip edilen tek bir sınıf, bir veya daha fazla karakter tekrarıyla eşleşir ve en uzun diziyi eşleştirir,
- "-" ile takip edilen tek bir sınıf, sıfır veya daha fazla karakter tekrarıyla eşleşir ve en kısa diziyi eşleştirir,
- "*" ile takip edilen tek bir sınıf, sıfır veya daha fazla karakter tekrarıyla eşleşir ve en uzun diziyi eşleştirir,
- "?" ile takip edilen tek bir sınıf, bir veya sıfır karakterle eşleşir,
- %n (burada `n` 1 ile 9 arasında bir rakamdır), `n`'inci yakalamayla eşleşir (sonraki bölüme bakın),
- %b`xy`, `x` ile başlayıp `y` ile biten metinlerle eşleşir, "%b()", "(" ile başlayıp ")" ile biten bir metinle eşleşir,
- %f[`set`] sonraki karakterin `set`'e ait olduğu ve önceki karakterin `set`'e ait olmadığı herhangi bir pozisyondaki boş bir metinle eşleşir. Konunun başlangıcı ve sonu sanki '\0' karakteriymiş gibi ele alınır.

Kalıplar şu şekilde sabitlenebilir:

- kalıbı "^" ile başlatmak, metnin başındaki bir dizeyle eşleşir,
- kalıbı "$" ile bitirmek, metnin sonundaki bir dizeyle eşleşir,
- kalıbı sabitlememek, metnin herhangi bir pozisyonundaki bir dizeyle eşleşir.

Bu iki karakterin yalnızca yukarıda belirtildiği şekilde konumlandırıldıklarında bir anlamı vardır. Diğer herhangi bir pozisyonda, bu karakterlerin bir anlamı yoktur ve kendilerini temsil ederler.

### Yakalamalar (Captures)

Kalıplar ayrıca "()" içine alınmış alt kalıplar da içerebilir. Yakalamalar, kalıptan belirli bir eşleşmeyi döndürmek veya değiştirmek için string.match ve string.gsub gibi fonksiyonlarda kullanılır. Bunların nasıl kullanılacağına dair örnekler aşağıda bulunabilir.

### Kullanım

Şimdi size yukarıdaki tüm bu şeyleri gerçekte nasıl kullanacağınızı göstereceğim. Aşağıdaki örnekler, yukarıda listelenen dört fonksiyonun nasıl kullanılacağını açıklamaktadır.

#### string.find

```lua
string.find( string str, string pattern [, number start [, boolean plain ]] )
```

`str` aranacak metin, `pattern` bulunacak kalıp metni, `start` başlangıç indeksi ve `plain` ise kalıp araması mı yoksa sadece düz metin araması mı kullanılacağını belirten bir booleandır. Fonksiyon, eşleşen alt metnin başlangıç ve bitiş indekslerini (başlangıç indeksi ve uzunluk değil) döndürür. Kalıbın yakalamaları varsa, bunlar indekslerden sonra döndürülür. Bir eşleşme bulunamazsa, fonksiyon nil döndürür.

Aşağıdaki kod, metindeki ilk kelimeyi bulacaktır.

```lua
local str = "1. Don't spam!"
local pattern = "([%a']+)" -- will match a substring that has one or more letter or apostrophes (')
local start, endpos, word = string.find( str, pattern )

print( start, endpos, word )
```

Çıktı:

```lua
4	8	Don't
```

Muhtemelen bunun [string.Explode](https://gmod.tr/wiki/string.Explode) ve birkaç döngü ile yapılabileceğini düşünüyorsunuz, ama bakın, bunu üç satırda yaptık.

Aşağıdaki kod, bir metnin yasaklı karakterler kümesiyle karşılaştırarak dosya adı olarak kullanılmasının güvenli olup olmadığını kontrol edecektir.

```lua
local str = "cry|*to"
local pattern = '[\\/:%*%?"<>|]' -- a set of all restricted characters
local start = string.find( str, pattern )

print( "String is "..( ( start ~= nil ) and "unsafe" or "safe" ) )
```

Çıktı:

```lua
String is unsafe
```

[string.find](https://gmod.tr/wiki/string.find), eşleşme bulunamazsa `nil` döndürür. Bu, bir eşleşme yapıldığında "unsafe" (güvensiz) ve aksi takdirde "safe" (güvenli) yazdırmak için boole mantığını kullanabileceğimiz anlamına gelir.

#### string.match

```lua
string.match( string str, string pattern [, number start] )
```

`str` aranacak metin, `pattern` bulunacak kalıp ve `start` başlangıç pozisyonudur. Bir eşleşme varsa, fonksiyon kalıptan yakalamaları döndürür, eğer yakalama yoksa tüm eşleşmeyi döndürür. Bir eşleşme bulunamazsa, fonksiyon `nil` döndürür.

Aşağıdaki kod, basit bir anahtar-değer (keyvalue) satırını ayrıştıracaktır.

```lua
local str = "key=  value"
--The following will match "variable name, 0 or more spaces, equals sign, 0 or more spaces, variable name":
local pattern = "([%w_]+)%s*=%s*([%w_]+)"
local k, v = string.match( str, pattern )

print( k, v )
```

Çıktı:

```lua
key	value
```

Aşağıdaki kod, metnin .lua uzantısıyla bitip bitmediğini kontrol edecektir.

```lua
local str = "teel.lua"
local pattern = ".+%.lua$" -- anything until a dot and "lua" at the end of the string
local match = string.match( str, pattern )

print( "String ends with "..( ( match ) and ".lua" or "something else" ) )
```

Çıktı:

```lua
String ends with .lua
```

#### string.gmatch

```lua
string.gmatch( string str, string pattern )
```

`str` aranacak metin ve `pattern` aranacak kalıptır. Fonksiyon, metindeki her eşleşmeyi gezen ve kalıbın yakalamalarını (varsa) veya yakalama yoksa tüm eşleşmeyi döndüren bir yineleyici (döngüler tarafından kullanılan özel fonksiyonlar) fonksiyonu döndürür. Fonksiyon, bir eşleşme bulunamadığı durumda nil döndürmez, bunun yerine döngüyü başlatmayacak 'boş' bir yineleyici fonksiyonu döndürür.

Aşağıdaki kod, metindeki her kelimeyi gezer.

```lua
local str = "This is PATTERNS"
local pattern = "%w+" -- will match any word

for word in string.gmatch( str, pattern ) do

	print( word )

end
```

Çıktı:

```lua
This
is
PATTERNS
```

string.match içinde kullandığınız herhangi bir kalıp gmatch içinde de kullanılabilir, ancak sadece ilk eşleşmeyi bulmak yerine, metindeki her eşleşmeyi bulur.

Aşağıdaki kod, anahtar-değer ayrıştırma kalıbını kullanır ancak artık bir anahtar-değer listesini okuyabilir.

```lua
local str = "key = value key2 =  value2"
local pattern = "([%w_]+)%s*=%s*([%w_]+)" -- same pattern as above

local tbl = { }
for k, v in string.gmatch( str, pattern ) do

	tbl[ k ] = v

end

PrintTable( tbl )
```

Çıktı:

```lua
key = value
key2 = value2
```

İlginç olan, metnin anahtar-değer çiftleri arasında ayırıcı olarak herhangi bir karaktere sahip olabilmesidir.

#### string.gsub

```lua
string.gsub( string str, string pattern, string/table/function repl )
```

`str` içinde arama yapılacak metin, `pattern` aranacak kalıp ve `repl` yerine konulacak değerdir. Fonksiyon, kalıbın tüm tekrarlarının `repl` ile verilen değerle değiştirildiği `str`'yi ve ikinci argüman olarak toplam eşleşme sayısını döndürür.

`repl` aşağıdaki şeyler olabilir:

- **bir metin (string)** - bu durumda kalıbın tüm tekrarları bu metinle değiştirilir, "%0" özel durumu tüm eşleşmeyi temsil etmek üzere "%n" öğesi de desteklenir,
- **bir fonksiyon** - bu durumda, her eşleşme gerçekleştiğinde geçirilen fonksiyona argüman(lar)ı olarak eşleşme/yakalamalar verilir ve eşleşme, fonksiyon tarafından döndürülen değerle değiştirilir,
- **bir tablo (table)** - bu durumda, ilk yakalama (veya yakalama yoksa eşleşme) ile indekslenen değer döndürülür.

Eğer fonksiyon veya tablo `nil` ya da `false` döndürürse, eşleşme göz ardı edilir ve hiçbir şey değiştirilmez.

Aşağıdaki kod, bir anahtar-değer çiftini bir xml düğümü olarak biçimlendirir.

```lua
local str = "key = value"
local pattern = "([%w_]+)%s*=%s*([%w_]+)"
local replacement = "<%1>%2</%1>"

local output = string.gsub( str, pattern, replacement )

print( output )
```

Çıktı:

```lua
<key>value</key>
```

Aşağıdaki örnek, .NET biçimlendirme özelliği gibi çalışan bir fonksiyon oluşturur.

```lua
function string.format2( fmt, ... )

	// 'arg' is the ... combined in a table
	local arg = { ... }
	return fmt:gsub( "{(%d+)}", function( i ) return arg[ tostring( i ) + 1 ] end )

end

local str = "This is {0}, oh {1}.."
local repl1 = "PATTERNS"
local repl2 = "YEAH"

local output = string.format2( str, repl1, repl2 )

print( output )
```

Çıktı:

```lua
This is PATTERNS, oh YEAH..
```

### Sonuç

Makale nihayet bitti! Umarım tüm bunlardan yeni bir şeyler öğrenmişsinizdir. Lua'nın kalıpları doğru kullanıldığında çok güçlüdür. Metinlere (string) yoğun bir şekilde dayanan bir eklenti yaparken, kalıplar büyük olasılıkla işinize yarayacaktır. [Lua kılavuzunda](http://www.lua.org/manual/5.2/) veya [PIL](http://www.lua.org/pil/)'de (Programming in Lua) yeni örnekler bulabilirsiniz.

İyi günler!

### Ayrıca bakınız

- [Resmi 5.3 Kalıplar Eğitimi (PiL)](http://www.lua.org/manual/5.3/manual.html#6.4.1)

- [GMod Wiki ana sayfası](https://gmod.tr/wiki)

---

[Tüm sunucular](https://gmod.tr/) · [GmodTR Launcher](https://gmod.tr/launcher) · [Rehber](https://gmod.tr/rehber) · [GMod Wiki](https://gmod.tr/wiki) · [GmodTR nedir?](https://gmod.tr/hakkinda) · [Sunucu ekle](https://gmod.tr/sunucu-ekle) · [Discord](https://discord.gg/gmodtr)

Kaynak: https://gmod.tr/wiki/Patterns
