Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Regex'in Bedeli: ReDoS, Catastrophic Backtracking, Okunabilirlik ve Regex'i Test Etmek
İç içe quantifier, çakışan alternation ya da art arda .* içeren bir pattern, neredeyse eşleşen bir input'ta üstel ya da polinom sayıda deneme yapar; ölçümümüzde ^(a+)+$ 28 harfte .NET'te 10 saniye sürdü, NonBacktracking 0,07 ms. Tehlikeli yapıları PCRE2 adım sayılarıyla tanıyor, Cloudflare'in 2019 kesintisini, Angular validator'ı ve sunucu doğrulamasını, (?x) ile okunur pattern'i, xUnit [Theory] ile test tablosunu ve e-posta için MailAddress kararını gösteriyoruz.
.NET'te Regex: GeneratedRegex, RegexOptions, Timeout, NonBacktracking ve Span API'leri
Sabit pattern'ler için [GeneratedRegex] kullan, runtime'da belli olan pattern'leri bir kez oluşturup sakla ve güvenilmeyen input'ta timeout ya da NonBacktracking ver; her çağrıda new Regex(..., Compiled) ölçümümüzde source generator'dan otuz üç bin kat yavaştı. BenchmarkDotNet ölçümü, allocation yapmayan EnumerateMatches, timeout ve NonBacktracking'in reddettiği yapılar, IgnoreCase'in kültürü ne zaman okuduğu ve Bookstore için ISBN doğrulama ile Türkçe slug üretimi gerçek çıktılarla.
Komut Satırında ve IDE'de Regex: grep -E/-P, ripgrep, sed, git grep, PowerShell ve Repo Genelinde Find/Replace
Repo genelinde regex ile değişikliği güvenli yapmanın sırası şu: temiz çalışma ağacı, dosya listesini git grep ile almak, rg -r ile önizlemek, sed -E ile uygulamak ve git diff ile kontrol etmek. grep, ripgrep, PowerShell ve IDE'lerin regex farklarını, Bookstore'da interpolation'lı log çağrılarını message template'e çeviren gerçek bir refactor'u ve CRLF'li dosyada $'ın neden eşleşmediğini .NET 11'in AnyNewLine option'ıyla birlikte gösteriyoruz.
Regex Flavor'ları: .NET, JavaScript, PCRE2, POSIX BRE/ERE ve RE2 Arasındaki Farklar, Glob ile Regex'i Ayırmak
Aynı pattern flavor'a göre çalışır, hata verir ya da hata vermeden başka bir şey eşleştirir: Perl ailesi (.NET, JavaScript, PCRE2) backtracking ile lookaround sunar, RE2 ve Rust regex lineer zaman için bunlardan vazgeçer, POSIX en uzun eşleşmeyi seçer. Aynı probe listesini beş engine'de çalıştırıyor, Prometheus'un =~ ile tam eşleşmesini promtool ile, glob ile regex farkını .gitignore ve PowerShell ile gösteriyoruz.
Lookaround, Inline Flag'ler ve Unicode: Lookahead, Lookbehind, (?i), \p{L} ve Türkçe Karakterler
Lookahead ve lookbehind karakter tüketmeden bir pozisyonun önünü ya da arkasını kontrol eder; değişken uzunluklu lookbehind .NET ve JavaScript'te çalışır, PCRE2'de sınırlı, ripgrep'te hiç yoktur. Inline flag'leri ve JavaScript'in (?i:…) modifier'larını, \p{L} ile v flag'ini, .NET'te IgnoreCase'in kültüre bağlı olduğu için ıssız ile ISSIZ'in eşleşip eşleşmediğinin ortama göre değiştiğini gerçek çıktılarla gösteriyoruz.
Gruplar ve Backreference: Capture, Named Group, Non-capturing, Alternation ve Replace'te $1/${name}
Capture group'lar açılış parantezinin sırasıyla numaralanır, ama .NET isimli grupları en sona koyduğu için aynı $2/$1 replacement'ı .NET'te ve JavaScript'te farklı sonuç verir. Named group yazımlarını, ES2025'in tekrar eden grup isimlerini, backreference ile tekrar eden kelimeyi, POSIX'in en uzun eşleşme kuralını ve .NET, JavaScript, sed ve VS Code'un replace syntax'ını gerçek çıktılarla karşılaştırıyor, Bookstore'un CSV'sinde yazar adlarını çeviriyoruz.
Quantifier'lar ve Backtracking: Greedy, Lazy, Possessive ve Atomic Group
Greedy quantifier önce alabildiğini alır ve pattern'in geri kalanı tutmazsa karakter karakter geri verir; lazy quantifier az alıp tek tek ekler, ama ikisi de ayırıcıyı arayarak adım harcar ve en doğru, en hızlı yol çoğu zaman negated class'tır. PCRE2'nin adım sayılarıyla greedy, lazy, possessive ve atomic group'u karşılaştırıyor, Bookstore'un access log'undan endpoint, status ve süreyi .NET, JavaScript ve sed ile çekiyoruz.
Regular Expression Nasıl Okunur? Literal, Metakarakter, Character Class, Anchor ve Escape Kuralları
Engine pattern'i input'un her başlangıç pozisyonunda soldan sağa dener ve en soldaki eşleşmeyi döndürür; metakarakterleri kaçışlamak, character class aralıklarını doğru yazmak ve anchor'ları bilmek bu yüzden şart. .NET'te \d'nin Arap-Hint rakamlarını, $'ın sondaki \n'i kabul ettiğini gerçek çıktılarla gösteriyor, ISBN-13 ve sipariş numarasını .NET, JavaScript ve grep ile doğruluyoruz.
Git Dostu API Client'ı: Bruno ile Collection'ı Repo'da Tutmak, OpenCollection YAML ve CLI ile CI'da Koşmak
Bruno collection'ı OpenCollection YAML dosyaları olarak repo'da tutup GitHub Actions'ta Bruno CLI ile koşmak, istek değişikliklerini code review'da okunur bir diff'e çeviriyor. Bookstore için auth miras alan bir collection, OpenAPI ve Postman import'u (pm.variables.get'in bru.getVar'a yanlış çevrilmesi), .env ile secret'lar, assertion ve test script'leri, JUnit/HTML raporu, rapor klasörü olmayınca 2 dönen CLI ve YAML collection'ındaki .bru dosyasını sessizce atlayan run gerçek koşularla.
Postman Derinlemesine: Collection, Environment, Variable Scope'ları, Script'ler, Test'ler, Mock Server ve CLI
Postman collection'ını repo'da tutup CI'da Newman ya da Postman CLI ile koşmak, Mart 2026'dan beri tek kullanıcılı ücretsiz plana karşı en sağlam yol. Bookstore için elle yazılmış v2.1 collection: OpenAPI'den import, variable scope önceliği, shared ve local value farkı, token'ı bir kez alıp saklayan pre-request script, pm.test, data dosyasıyla düşen bir iterasyon, JUnit raporu ve Postman CLI'ın yerel mock'unun neden işe yaramaz veri döndürdüğü gerçek koşularla.
.http Dosyalarıyla Repo İçinde API Testi: Visual Studio, Rider ve VS Code'da Variable, Environment ve Request Chaining
.http dosyaları repo'da yaşar ama aynı uzantının üç dialect'i var: Visual Studio'nun {{login.response.body.$.accessToken}}, $dotenv ve $shared'ı, JetBrains HTTP Client'ta (ijhttp 2026.2) çözülmeden gidiyor ve 401'ler test yazılmadıkça hata sayılmıyor. Bookstore için iki dosya, http-client.env.json ve secret provider'lar, VS Code ayarları, client.test ile JUnit raporu, .gitignore'un korumadığı http-client.private.env.json ve gitleaks'in yakaladığı token gerçek koşularla.
curl ile API Test Etmek: Method, Header, --json, Authentication, Upload, Hata Kodları ve Script'te Kullanmak
curl'ü script'te güvenle kullanmanın kuralı, 401 ve 500'de de 0 dönen çıkış koduna güvenmemek: --fail-with-body hem 22 ile çıkar hem ProblemDetails'i basar. Bookstore.Api'ye karşı -v ve --trace-ascii, -d ile --json farkı (415), token'ı --variable ve -H @dosya ile history'den uzak tutmak, -F ile kapak yükleme ve antiforgery hatası, --retry sınırları, bir smoke script'i, Windows'ta curl.exe tırnak sorunu, Invoke-RestMethod ve xh gerçek çıktılarla.