Skip to content

Commit

Permalink
Merge pull request javascript-tutorial#355 from cys27/master
Browse files Browse the repository at this point in the history
Quantifiers +, *, ? and {n}
  • Loading branch information
sahinyanlik authored Apr 26, 2024
2 parents e419a0e + f987d4c commit 132e3a6
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 69 deletions.
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

Solution:
Çözüm:

```js run
let regexp = /\.{3,}/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....
alert( "Merhaba!... Nasıl gidiyor?.....".match(regexp) ); // ..., .....
```

Please note that the dot is a special character, so we have to escape it and insert as `\.`.
Lütfen noktanın özel bir karakter olduğunu unutmayın, bu yüzden `\.` ekleyerek ondan kurtulmamız gerekiyor.
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ importance: 5

---

# How to find an ellipsis "..." ?
# Üç noktayı nasıl buluruz "..." ?

Create a regexp to find ellipsis: 3 (or more?) dots in a row.
Üç noktayı bulmak için bir düzenli ifade oluşturun: Art arda 3 nokta (veya daha fazlası?).

Check it:
Kontrol et:

```js
let regexp = /your regexp/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....
let regexp = /duzenli ifaden/g;
alert( "Merhaba!... Nasıl gidiyor?.....".match(regexp) ); // ..., .....
```
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
We need to look for `#` followed by 6 hexadecimal characters.
`#` ve ardından 6 tane onaltılık karakterin gelmesine ihtiyacımız var.

A hexadecimal character can be described as `pattern:[0-9a-fA-F]`. Or if we use the `pattern:i` flag, then just `pattern:[0-9a-f]`.
Onaltılık bir karakter `pattern:[0-9a-fA-F]` şeklinde ifade edilebilir. Veya eğer `pattern:i` bayrağını kullanırsak, `pattern:[0-9a-f]` şeklinde ifade edilebilir.

Then we can look for 6 of them using the quantifier `pattern:{6}`.
Daha sonrasında `pattern:{6}` nicelik belirtecini kullanarak bunlardan 6 tanesini seçebiliriz.

As a result, we have the regexp: `pattern:/#[a-f0-9]{6}/gi`.
Sonuç olarak, `pattern:/#[a-f0-9]{6}/gi` düzenli ifadesine sahibiz.

```js run
let regexp = /#[a-f0-9]{6}/gi;
Expand All @@ -14,18 +14,18 @@ let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2"
alert( str.match(regexp) ); // #121212,#AA00ef
```

The problem is that it finds the color in longer sequences:
Buradaki sorun daha uzun değerleri de bulmasıdır:

```js run
alert( "#12345678".match( /#[a-f0-9]{6}/gi ) ) // #12345678
```

To fix that, we can add `pattern:\b` to the end:
Bunu çözmek için, sona `pattern:\b` ekleyebiliriz:

```js run
// color
// renk
alert( "#123456".match( /#[a-f0-9]{6}\b/gi ) ); // #123456

// not a color
// bir renk değil
alert( "#12345678".match( /#[a-f0-9]{6}\b/gi ) ); // null
```
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
# Regexp for HTML colors
# HTML renkler için düzenli ifade (regexp)

Create a regexp to search HTML-colors written as `#ABCDEF`: first `#` and then 6 hexadecimal characters.
`#ABCDEF` şeklinde yazılmış HTML-renklerini aramak için bir düzenli ifade oluşturun: önce `#` ve ardından 6 tane onaltılık karakter gelmesi lazım.

An example of use:
Bir kullanım örneği:

```js
let regexp = /...your regexp.../
let regexp = /...senin duzenli ifaden.../

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2 #12345678";

alert( str.match(regexp) ) // #121212,#AA00ef
```

P.S. In this task we do not need other color formats like `#123` or `rgb(1,2,3)` etc.
NOT: Bu görevde `#123` veya `rgb(1,2,3)` vb. diğer renk formatlarına ihtiyacımız yoktur.
95 changes: 47 additions & 48 deletions 9-regular-expressions/09-regexp-quantifiers/article.md
Original file line number Diff line number Diff line change
@@ -1,46 +1,46 @@
# Quantifiers +, *, ? and {n}
# Nicelik Belirteçleri +, *, ? and {n}

Let's say we have a string like `+7(903)-123-45-67` and want to find all numbers in it. But unlike before, we are interested not in single digits, but full numbers: `7, 903, 123, 45, 67`.
Diyelim ki `+7(903)-123-45-67` şeklinde bir karakter dizimiz var ve biz bu dizideki sayıların tamamını bulmak istiyoruz. Ama öncekinden farklı olarak, tek bir sayıyla değil, bütün sayılarla ilgileniyoruz: `7, 903, 123, 45, 67`.

A number is a sequence of 1 or more digits `pattern:\d`. To mark how many we need, we can append a *quantifier*.
Sayı, bir veya daha fazla rakamdan oluşan bir dizidir `pattern:\d`. Kaç tanesine sahip olduğumuzu işaretlemek için bir *nicelik belirteci* ekleyebiliriz.

## Quantity {n}
## Nicelik {n}

The simplest quantifier is a number in curly braces: `pattern:{n}`.
En basit nicelik belirteci, süslü parantezler içindeki bir sayıdır: `pattern:{n}`.

A quantifier is appended to a character (or a character class, or a `[...]` set etc) and specifies how many we need.
Bir karaktere (ya da bir karakter sınıfına, veya `[...]` kümesine vb.) nicelik belirteci eklendiğinde, bize kaç tanesine sahip olduğumuzu belirtir.

It has a few advanced forms, let's see examples:
Birkaç gelişmiş formu var, örneklere bakalım:

The exact count: `pattern:{5}`
: `pattern:\d{5}` denotes exactly 5 digits, the same as `pattern:\d\d\d\d\d`.
Tam sayım: `pattern:{5}`
: `pattern:\d{5}`, `pattern:\d\d\d\d\d` ile benzerdir. İkiside tam olarak 5 adet rakamı belirtir.

The example below looks for a 5-digit number:
Aşağıdaki örnekte 5 basamaklı sayı aranır:

```js run
alert( "I'm 12345 years old".match(/\d{5}/) ); // "12345"
alert( "12345 yaşındayım".match(/\d{5}/) ); // "12345"
```

We can add `\b` to exclude longer numbers: `pattern:\b\d{5}\b`.
Daha uzun sayıları hariç tutmak için `\b` kullanabiliriz: `pattern:\b\d{5}\b`.

The range: `pattern:{3,5}`, match 3-5 times
: To find numbers from 3 to 5 digits we can put the limits into curly braces: `pattern:\d{3,5}`
`pattern:{3,5}`, 3 ila 5 aralığında eşleştirir
: 3 ila 5 basamaklı sayıları bulmak için sınırları süslü parantezlerin içinde belirtebiliriz: `pattern:\d{3,5}`

```js run
alert( "I'm not 12, but 1234 years old".match(/\d{3,5}/) ); // "1234"
alert( "12 yaşında değilim, 1234 yaşındayım.".match(/\d{3,5}/) ); // "1234"
```

We can omit the upper limit.
Üst sınırı kaldırabiliriz.

Then a regexp `pattern:\d{3,}` looks for sequences of digits of length `3` or more:
`pattern:\d{3,}`, `3` veya daha fazla basamaklı sayıları arar:

```js run
alert( "I'm not 12, but 345678 years old".match(/\d{3,}/) ); // "345678"
alert( "12 yaşında değilim, 345678 yaşındayım".match(/\d{3,}/) ); // "345678"
```

Let's return to the string `+7(903)-123-45-67`.
Şimdi `+7(903)-123-45-67` değerine dönelim.

A number is a sequence of one or more digits in a row. So the regexp is `pattern:\d{1,}`:
Sayı, arka arkaya bir veya daha fazla rakamdan oluşan bir dizidir. Yani düzenli ifade (regexp) şu şekilde olacaktır, `pattern:\d{1,}`:

```js run
let str = "+7(903)-123-45-67";
Expand All @@ -50,14 +50,14 @@ let numbers = str.match(/\d{1,}/g);
alert(numbers); // 7,903,123,45,67
```

## Shorthands
## Kısaltmalar

There are shorthands for most used quantifiers:
Çok kullanılan nicelik belirteçlerinin kısaltmaları mevcuttur:

`pattern:+`
: Means "one or more", the same as `pattern:{1,}`.
: "bir veya daha fazlası" anlamına gelir, `pattern:{1,}` ifadesine benzerdir.

For instance, `pattern:\d+` looks for numbers:
Örneğin, `pattern:\d+` sayıları aramak içindir:

```js run
let str = "+7(903)-123-45-67";
Expand All @@ -66,11 +66,11 @@ There are shorthands for most used quantifiers:
```

`pattern:?`
: Means "zero or one", the same as `pattern:{0,1}`. In other words, it makes the symbol optional.
: "sıfır ya da bir" anlamına gelir, `pattern:{0,1}` ifadesine benzerdir. Başka bir deyişle, isteğe bağlı hale getirir.

For instance, the pattern `pattern:ou?r` looks for `match:o` followed by zero or one `match:u`, and then `match:r`.
Örneğin, `pattern:ou?r` kalıbı, ilk önce `match:o` için, ardından `match:u` (sıfır veya bir adet) için, ve daha sonrasında `match:r` için arama yapar.

So, `pattern:colou?r` finds both `match:color` and `match:colour`:
Yani, `pattern:colou?r`, hem `match:color` hem de `match:colour` öğelerini bulur:

```js run
let str = "Should I write color or colour?";
Expand All @@ -79,64 +79,63 @@ There are shorthands for most used quantifiers:
```

`pattern:*`
: Means "zero or more", the same as `pattern:{0,}`. That is, the character may repeat any times or be absent.
: "Sıfır veya daha fazlası" anlamına gelir, `pattern:{0,}` ile benzerdir. Yani bir karakter kendini tekrar edebilir veya hiç olmayabilir:

For example, `pattern:\d0*` looks for a digit followed by any number of zeroes (may be many or none):
Örnek olarak, `pattern:\d0*`, bir sayı ve ardından onu takip eden sıfırları arar (çok sayıda sıfır olabilir ya da hiç olmayabilir):

```js run
alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1
```

Compare it with `pattern:+` (one or more):
Bunu `pattern:+` (bir veya daha fazlası) ile karşılaştıralım:

```js run
alert( "100 10 1".match(/\d0+/g) ); // 100, 10
// 1 not matched, as 0+ requires at least one zero
// 1 eşleşmedi, çünkü 0+ ifadesi en az bir sıfır varlığını gerektirir.
```

## More examples
## Daha Fazla Örnek

Quantifiers are used very often. They serve as the main "building block" of complex regular expressions, so let's see more examples.
Nicelik belirteçleri sıklıkla kullanılır. Karmaşık düzenli ifade kalıplarının (regexp pattern) "yapı taşı" olarak kullanılırlar. Bu yüzden daha fazla örnek görelim.

**Regexp for decimal fractions (a number with a floating point): `pattern:\d+\.\d+`**
**Ondalık kesirler için düzenli ifadeler (regexp) (kayan noktalı bir sayı): `pattern:\d+\.\d+`**

In action:
```js run
alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345
```

**Regexp for an "opening HTML-tag without attributes", such as `<span>` or `<p>`.**
**"Nitelik barındırmayan HTML açılış etiketleri" için bir düzenli ifade (regexp),`<span>` veya `<p>` gibi.**

1. The simplest one: `pattern:/<[a-z]+>/i`
1. En basit olanı: `pattern:/<[a-z]+>/i`

```js run
alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>
```

The regexp looks for character `pattern:'<'` followed by one or more Latin letters, and then `pattern:'>'`.
Bu düzenli ifade (regexp), ilk olarak `pattern:'<'` in, ardından bir veya daha fazla Latin harfi için ve daha sonrasında `pattern:'>'`in bir arama yapar.

2. Improved: `pattern:/<[a-z][a-z0-9]*>/i`
2. Gelişmiş hali: `pattern:/<[a-z][a-z0-9]*>/i`

According to the standard, HTML tag name may have a digit at any position except the first one, like `<h1>`.
Standarda göre HTML etiket isimleri `<h1>` gibi ilk karakter dışında herhangi bir pozisyonda bir rakam içerebilir.

```js run
alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1>
```

**Regexp "opening or closing HTML-tag without attributes": `pattern:/<\/?[a-z][a-z0-9]*>/i`**
**"Nitelik barındırmayan HTML açılış ve kapanış etiketleri"in düzenli ifade (regexp): `pattern:/<\/?[a-z][a-z0-9]*>/i`**

We added an optional slash `pattern:/?` near the beginning of the pattern. Had to escape it with a backslash, otherwise JavaScript would think it is the pattern end.
Kalıbın başında `pattern:/?` ile isteğe bağlı bir eğik çizgi (slash) belirttim. Ters eğik çizgiyle (backslash) bundan kurtuldum, aksi takdirde JavaScript bunun, düzenli ifade kalıbının sonu olduğunu düşünecekti.

```js run
alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
alert( "<h1>Merhaba!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
```

```smart header="To make a regexp more precise, we often need make it more complex"
We can see one common rule in these examples: the more precise is the regular expression -- the longer and more complex it is.
```smart header="Bir düzenli ifadeyi daha tutarlı/kesin hale getirmek için genellikle onu daha karmaşık hale getirmek gerekir"
Bu örneklerde genel bir kural görebiliriz: düzenli ifade ne kadar tutarlı/kesin ise o kadar uzun ve karmaşıktır.
For instance, for HTML tags we could use a simpler regexp: `pattern:<\w+>`. But as HTML has stricter restrictions for a tag name, `pattern:<[a-z][a-z0-9]*>` is more reliable.
Örneğin, HTML etiketleri için daha basit bir ifade kullanabiliriz: `pattern:<\w+>`. Ancak HTML, etiket isimleri için kısıtlamalara sahip olduğundan dolayı, `pattern:<[a-z][a-z0-9]*>` daha güvenilirdir.
Can we use `pattern:<\w+>` or we need `pattern:<[a-z][a-z0-9]*>`?
`pattern:<\w+>` kalıbını kullanabilir miyiz yoksa `pattern:<[a-z][a-z0-9]*>` kalıbını mı kullanmamız gerekir?
In real life both variants are acceptable. Depends on how tolerant we can be to "extra" matches and whether it's difficult or not to remove them from the result by other means.
Gerçek hayatta ikiside kabul edilebilir. "Ekstra" eşleşmelere ne kadar tahammül edebileceğimize ya da bunları başka yollarla sonuçtan çıkarmanın zor olup olmadığına bağlıdır.
```

0 comments on commit 132e3a6

Please sign in to comment.