Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Capturing groups #109

Merged
merged 10 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions 9-regular-expressions/11-regexp-groups/01-test-mac/solution.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
A two-digit hex number is `pattern:[0-9a-f]{2}` (assuming the flag `pattern:i` is set).
একটি দুই অঙ্কবিশিষ্ট হেক্সাডেসিমেল নাম্বারের প্যাটার্ন হল `pattern:[0-9a-f]{2}` (ধরে নিই, `pattern:i` ফ্ল্যাগ সেট আছে)।

We need that number `NN`, and then `:NN` repeated 5 times (more numbers);
সুতরাং আমাদের এই নাম্বারটি `NN` লাগবে, এবং এটির `:NN` ৫ বার পুনরাবৃত্তি হবে;

The regexp is: `pattern:[0-9a-f]{2}(:[0-9a-f]{2}){5}`
সুতরাং রেগুলার এক্সপ্রেশনটি হবে: `pattern:[0-9a-f]{2}(:[0-9a-f]{2}){5}`

Now let's show that the match should capture all the text: start at the beginning and end at the end. That's done by wrapping the pattern in `pattern:^...$`.
এখন চলুন ম্যাচটি শুরু থেকে শেষ পর্যন্ত সকল পুরো লাইনটি পাঠ করার উপযোগী করি। এজন্য সম্পূর্ন প্যাটার্নটি `pattern:^...$` এর মধ্যে লিখি।

Finally:
শেষ পর্যন্ত:

```js run
let regexp = /^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$/i;

alert( regexp.test('01:32:54:67:89:AB') ); // true
alert( regexp.test('01:32:54:67:89:AB') ); // সত্য

alert( regexp.test('0132546789AB') ); // false (no colons)
alert( regexp.test('0132546789AB') ); // মিথ্যা (কোলন নেয়)

alert( regexp.test('01:32:54:67:89') ); // false (5 numbers, need 6)
alert( regexp.test('01:32:54:67:89') ); // মিথ্যা (৫টি নাম্বার, অবশ্যই ৬টি হতে হবে)

alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ in the end)
alert( regexp.test('01:32:54:67:89:ZZ') ) // মিথ্যা (শেষে ZZ)
```
20 changes: 10 additions & 10 deletions 9-regular-expressions/11-regexp-groups/01-test-mac/task.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# Check MAC-address
# MAC-address যাচাই

[MAC-address](https://en.wikipedia.org/wiki/MAC_address) of a network interface consists of 6 two-digit hex numbers separated by a colon.
[MAC-address](https://en.wikipedia.org/wiki/MAC_address) হল নেটওয়ার্ক ইন্টারফেসের ৬ টি দুই অঙ্কবিশিষ্ট একটি হেক্সাডেসিমেল নাম্বার যা কোলন দ্বারা পৃথক থাকে।

For instance: `subject:'01:32:54:67:89:AB'`.
যেমন: `subject:'01:32:54:67:89:AB'`

Write a regexp that checks whether a string is MAC-address.
MAC-address যাচাইয়ের জন্য একটি রেগুলার এক্সপ্রেশন লিখুন।

Usage:
উদাহরণস্বরুপ:
```js
let regexp = /your regexp/;
let regexp = /আপনার প্যাটার্ন লিখুন/;

alert( regexp.test('01:32:54:67:89:AB') ); // true
alert( regexp.test('01:32:54:67:89:AB') ); // সত্য

alert( regexp.test('0132546789AB') ); // false (no colons)
alert( regexp.test('0132546789AB') ); // মিথ্যা (কোলন নেয়)

alert( regexp.test('01:32:54:67:89') ); // false (5 numbers, must be 6)
alert( regexp.test('01:32:54:67:89') ); // মিথ্যা (৫টি নাম্বার, অবশ্যই ৬টি হতে হবে)

alert( regexp.test('01:32:54:67:89:ZZ') ) // false (ZZ ad the end)
alert( regexp.test('01:32:54:67:89:ZZ') ) // মিথ্যা (শেষে ZZ)
```
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
A regexp to search 3-digit color `#abc`: `pattern:/#[a-f0-9]{3}/i`.
৩ অঙ্কবিশিষ্ট সংখ্যা খুঁজার রেগুলার এক্সপ্রেশন হল `#abc`: `pattern:/#[a-f0-9]{3}/i`

We can add exactly 3 more optional hex digits. We don't need more or less. The color has either 3 or 6 digits.
এরপর আমরা শুধুমাত্র আরো ৩অঙ্কবিশিষ্ট অপশনাল হেক্সাডেসিমেল নাম্বার খুঁজার প্যাটার্ন লিখব, আমাদের এর বেশি বা কমের জন্য লাগবে না। সুতরাং কালারটি হবে ৩ বা ৬ অঙ্কের।

Let's use the quantifier `pattern:{1,2}` for that: we'll have `pattern:/#([a-f0-9]{3}){1,2}/i`.
চলুন এই জন্য এই কোয়ান্টিফায়ারটি `pattern:{1,2}` ব্যবহার করি: আমাদের প্যাটার্নটি হবে `pattern:/#([a-f0-9]{3}){1,2}/i`

Here the pattern `pattern:[a-f0-9]{3}` is enclosed in parentheses to apply the quantifier `pattern:{1,2}`.
এখানে আমরা এই প্যাটার্নটি `pattern:[a-f0-9]{3}` প্যারান্টেসিসের মধ্যে লিখব, যাতে এই কোয়ান্টিফায়ারটি `pattern:{1,2}` ব্যবহার করা যায়।

In action:
এখানে দেখুন:

```js run
let regexp = /#([a-f0-9]{3}){1,2}/gi;
Expand All @@ -16,7 +16,7 @@ let str = "color: #3f3; background-color: #AA00ef; and: #abcd";
alert( str.match(regexp) ); // #3f3 #AA00ef #abc
```

There's a minor problem here: the pattern found `match:#abc` in `subject:#abcd`. To prevent that we can add `pattern:\b` to the end:
তবে এখানে একটি ছোট্ট সমস্যা আছে `match:#abc` এই স্ট্রিংয়ের জন্যও কাজ করবে `subject:#abcd`, যা সঠিক নয়। এজন্য আমাদের শেষে `pattern:\b` ব্যবহার করা লাগবে:

```js run
let regexp = /#([a-f0-9]{3}){1,2}\b/gi;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Find color in the format #abc or #abcdef
# এই কালার ফরম্যাটগুলো খুঁজুন #abc বা #abcdef

Write a RegExp that matches colors in the format `#abc` or `#abcdef`. That is: `#` followed by 3 or 6 hexadecimal digits.
একটি রেগুলার এক্সপ্রেশন লিখুন যা এই দুটি কালার ফরম্যাটের সাথে ম্যাচ করবে `#abc` বা `#abcdef`। এটি হবে: `#` দ্বারা ৩ বা ৬ অঙ্কের হেক্সাডেসিমেল নাম্বার।

Usage example:
উদাহরণস্বরুপ:
```js
let regexp = /your regexp/g;
let regexp = /আপনার প্যাটার্ন লিখুন/g;

let str = "color: #3f3; background-color: #AA00ef; and: #abcd";

alert( str.match(regexp) ); // #3f3 #AA00ef
```

P.S. This should be exactly 3 or 6 hex digits. Values with 4 digits, such as `#abcd`, should not match.
বি.দ্র. এটি অবশ্যই ৩ বা ৬ অঙ্কের হেক্সাডেসিমেল নাম্বার হতে হবে। যেমন, ৪ অঙ্কের সাথে `#abcd` এরা মিলবে না।
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
A positive number with an optional decimal part is (per previous task): `pattern:\d+(\.\d+)?`.
আমরা পূর্বের চ্যাপ্টারে ডেসিমেল সংখ্যা কে অপশনাল রেখে খুঁজার উপায় দেখেছিলাম: `pattern:\d+(\.\d+)?`

Let's add the optional `pattern:-` in the beginning:
ঋণাত্নক সংখ্যা খুঁজার জন্য শুরুতে `pattern:-` কে অপশনাল হিসেবে যোগ করি:

```js run
let regexp = /-?\d+(\.\d+)?/g;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Find all numbers
# সকল নাম্বার খুঁজুন

Write a regexp that looks for all decimal numbers including integer ones, with the floating point and negative ones.
সকল ডেসিমেল (পূর্ণ সংখ্যা এবং ঋণাত্নক) সংখ্যা খুঁজার একটি রেগুলার এক্সপ্রেশন লিখুন।

An example of use:
উদাহরণস্বরুপ:

```js
let regexp = /your regexp/g;
let regexp = /আপনার প্যাটার্ন লিখুন/g;

let str = "-1.5 0 2 -123.4.";

Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
A regexp for a number is: `pattern:-?\d+(\.\d+)?`. We created it in previous tasks.
সংখ্যা খুঁজার রেগুলার এক্সপ্রেশন: `pattern:-?\d+(\.\d+)?`। যা আমরা পূর্বের টাস্কে করেছিলাম।

An operator is `pattern:[-+*/]`. The hyphen `pattern:-` goes first in the square brackets, because in the middle it would mean a character range, while we just want a character `-`.
অপারেটর হল `pattern:[-+*/]`. হাইফেন `pattern:-` অবশ্যই ব্রাকেটের শুরুতে হতে হবে, কেননা মাঝে হলে এটি দ্বারা ক্যারাক্টারের রেঞ্জ বুঝায়, এখানে আমরা `-` কে ক্যারাক্টার হিসেবে ব্যবহার করতে চায়।

The slash `/` should be escaped inside a JavaScript regexp `pattern:/.../`, we'll do that later.
স্ল্যাশ `/` অবশ্যই জাভাস্ক্রিপ্টের রেগুলার এক্সপ্রেশনের মাঝে এস্কেপড `pattern:/.../` হয়, এটি আমরা এটি পরে দেখব।

We need a number, an operator, and then another number. And optional spaces between them.
আমাদের খুঁজা লাগবে একটি সংখ্যা অতঃপর একটি গাণিতিক চিহ্ন এবং শেষে আরো একটি সংখ্যা এবং তাদের মাঝের অতিরিক্ত স্পেস।

The full regular expression: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`.

It has 3 parts, with `pattern:\s*` between them:
1. `pattern:-?\d+(\.\d+)?` - the first number,
1. `pattern:[-+*/]` - the operator,
1. `pattern:-?\d+(\.\d+)?` - the second number.
সুতরাং রেগুলার এক্সপ্রেশনটি হবে: `pattern:-?\d+(\.\d+)?\s*[-+*/]\s*-?\d+(\.\d+)?`।

To make each of these parts a separate element of the result array, let's enclose them in parentheses: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`.
এর ৩টি অংশ আছে, সাথে এটিও `pattern:\s*`:
১. `pattern:-?\d+(\.\d+)?` - প্রথম সংখ্যাটি।
২. `pattern:[-+*/]` - গাণিতিক চিহ্নটি।
৩. `pattern:-?\d+(\.\d+)?` - দ্বিতীয় সংখ্যাটি।

In action:
তাদের প্রত্যেককে রেজাল্ট অ্যারের আলাদা আলাদা উপাদান হিসেবে রাখতে প্যারান্টেসিস দ্বারা গ্রুপ করি: `pattern:(-?\d+(\.\d+)?)\s*([-+*/])\s*(-?\d+(\.\d+)?)`।

যেমন:

```js run
let regexp = /(-?\d+(\.\d+)?)\s*([-+*\/])\s*(-?\d+(\.\d+)?)/;

alert( "1.2 + 12".match(regexp) );
```

The result includes:
রেজাল্টে:

- `result[0] == "1.2 + 12"` (full match)
- `result[1] == "1.2"` (first group `(-?\d+(\.\d+)?)` -- the first number, including the decimal part)
- `result[2] == ".2"` (second group`(\.\d+)?` -- the first decimal part)
- `result[3] == "+"` (third group `([-+*\/])` -- the operator)
- `result[4] == "12"` (forth group `(-?\d+(\.\d+)?)` -- the second number)
- `result[5] == undefined` (fifth group `(\.\d+)?` -- the last decimal part is absent, so it's undefined)
- `result[0] == "1.2 + 12"` (সম্পূর্ন এক্সপ্রেশনটি)
- `result[1] == "1.2"` (প্রথম গ্রুপ `(-?\d+(\.\d+)?)` -- প্রথম সংখ্যাটি, দশমিক অংশটিসহ)
- `result[2] == ".2"` (দ্বিতীয় গ্রুপ`(\.\d+)?` -- প্রথম দশমিক অংশটি)
- `result[3] == "+"` (তৃতীয় গ্রুপ `([-+*\/])` -- গাণিতিক চিহ্নটি)
- `result[4] == "12"` (চতুর্থ গ্রুপ `(-?\d+(\.\d+)?)` -- দ্বিতীয় সংখ্যাটি)
- `result[5] == undefined` (পঞ্চম গ্রুপ `(\.\d+)?` -- দ্বিতীয় দশমিক অংশটি অনুপস্থিত, সুতরাং এটি undefined)

We only want the numbers and the operator, without the full match or the decimal parts, so let's "clean" the result a bit.
আমরা শুধু সংখ্যাগুলো এবং গাণিতিক চিহ্নটি চায়, সম্পূর্ন অংশটি বা দশমিক অংশটি চায় না, সুতরাং আমাদের রেজাল্টকে আরো কিছুটা "clean" করি।

The full match (the arrays first item) can be removed by shifting the array `result.shift()`.
সম্পূর্ন অংশটি যা অ্যারের প্রথম ইলিমেন্ট একে আমরা `result.shift()` মেথডের সাহায্যে বাদ দিতে পারি।

Groups that contain decimal parts (number 2 and 4) `pattern:(.\d+)` can be excluded by adding `pattern:?:` to the beginning: `pattern:(?:\.\d+)?`.
যে গ্রুপগুলোতে দশমিক অংশ থাকে (২ এবং ৪ আইটেম) এই অংশের `pattern:(.\d+)` শুরুতে `pattern:?:` যোগ করে তাদের বাদ দিতে পারি: `pattern:(?:\.\d+)?`

The final solution:
সুতরাং সমাধানটি হবে:

```js run
function parse(expr) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# Parse an expression
# এক্সপ্রেশনকে পার্স

An arithmetical expression consists of 2 numbers and an operator between them, for instance:
একটি গাণিতিক সমীকরণে দুটি নাম্বার এবং তাদের মাঝে একটি গাণিতিক চিহ্ন আছে, যেমন:

- `1 + 2`
- `1.2 * 3.4`
- `-3 / -6`
- `-2 - 2`

The operator is one of: `"+"`, `"-"`, `"*"` or `"/"`.
গাণিতিক চিহ্নগুলো হল: `"+"`, `"-"`, `"*"` অথবা `"/"`

There may be extra spaces at the beginning, at the end or between the parts.
এখানে সমীকরণের শুরুতে,মাঝে এবং শেষে অতিরিক্ত স্পেস থাকতে পারে।

Create a function `parse(expr)` that takes an expression and returns an array of 3 items:
একটি ফাংশন লিখুন যা `parse(expr)` একটি সমীকরণ নিবে এবং তাদের কে একটি অ্যারের ৩ টি উপাদান হিসেবে রিটার্ন করবে:

1. The first number.
2. The operator.
3. The second number.
১. প্রথম সংখ্যাটি।
২. গাণিতিক চিহ্নটি।
৩. দ্বিতীয় সংখ্যাটি।

For example:
যেমন:

```js
let [a, op, b] = parse("1.2 * 3.4");
Expand Down
Loading