01/10/2018, 14:33

Nhờ giải thích ý nghĩa của Biểu thức chính quy

Chào mọi người. Đầu xuân xin được kính chúc anh chị em năm mới an khang thịnh vượng, vạn sự như ý.
Vừa bắt đầu trở lại làm việc và học tập, mình nhờ mọi người giải thích giúp mình biểu tức chính quy trong đoạn code dưới đây :

var str = 'For more information, see Chapter 3.4.5.1';
var re = /(chapter d+(.d)*)/i;
var found = str.match(re);
console.log(found);
// logs ['Chapter 3.4.5.1', 'Chapter 3.4.5.1', '.1']

Xin cho hỏi, biểu thức đã được khớp thế nào mà kết quả trả về có 2 giá trị đầu tiên giống nhau và giá trị thứ 3 là .1 cũng được thỏa mãn là sao ạ (vì mình thấy trong biểu thức chính quy có dính tới cả thằng chapter nữa mà ).

HK boy viết 16:41 ngày 01/10/2018

Theo như regex của bạn:

  • (chapter \d+(\.\d)*) là group 0 (full match)
  • chapter \d+(\.\d)* là group 1. Group 1 không khác gì group 0 tại vì chỉ cần thêm 1 cặp ngoặc bao ngoài group 0 là có group 1. Bỏ đi cho đỡ thừa.
  • \.\d là group 2.

Do vậy sẽ có 1 cái gì đó sẽ match vào group 2, đó chính là .1 (vì * có nghĩa là match nhiều nhất có thể -> pattern .1 cuối cùng sẽ match vào group 2). Bạn thử bỏ cái * xem, bạn sẽ thấy .4 sẽ match vào group 2.

Thinh Minh Ha viết 16:36 ngày 01/10/2018

Theo như regex của bạn:

(chapter \d+(.\d)*) là group 0 (full match)

chapter \d+(.\d)* là group 1. Group 1 không khác gì group 0 tại vì chỉ cần thêm 1 cặp ngoặc bao ngoài group 0 là có group 1. Bỏ đi cho đỡ thừa.

.\d là group 2.

Do vậy sẽ có 1 cái gì đó sẽ match vào group 2, đó chính là .1 (vì * có nghĩa là match nhiều nhất có thể -> pattern .1 cuối cùng sẽ match vào group 2). Bạn thử bỏ cái * xem, bạn sẽ thấy .4 sẽ match vào group 2.

Em thấy hơi khó hiểu ,anh có cách nào diễn giải dễ hỉu hơn chút xíu cho e hình dung được không anh
Cám ơn anh !

HK boy viết 16:39 ngày 01/10/2018

Bạn thử nhìn vào các matching group ở link dưới:

regex101.com

Online regex tester and debugger: PHP, PCRE, Python, Golang and JavaScript

Regex101 allows you to create, debug, test and have your expressions explained for PHP, PCRE, Python, Golang and JavaScript. The website also features a community where you can share useful expressions.

rồi xem bạn còn chưa hiểu thế nào.

Khoa Nguyen viết 16:47 ngày 01/10/2018

Bạn có thể viết lại cái regex thế này cho gọn.

/chapter [\.?\d]+/gi

Còn về cách hoạt động cụ thể thì có thể dùng http://regex101.com và đọc tài liệu về nó

Còn về matching group thì hiểu đơn giản là bao nhiêu cặp ngoặc đơn () thì bấy nhiêu matching group

Thinh Minh Ha viết 16:44 ngày 01/10/2018

(vì * có nghĩa là match nhiều nhất có thể -> pattern .1 cuối cùng sẽ match vào group 2). Bạn thử bỏ cái * xem, bạn sẽ thấy .4 sẽ match vào group 2.

Chỗ này em còn thắc mắc ạ:

Khi khớp đến Group này (\.\d)* dấu * tức là nhiều nhất có thể , vậy tại sao kết quả trả về lại chỉ là .1 mà không phải là .4.5.1 ạ.

Anh giải thích thêm cho e đoạn này với .

Khoa Nguyen viết 16:38 ngày 01/10/2018

Đầu tiên nó sẽ match cái trong ngoặc trước sau đó match cái trong ngoặc kèm *. Trong trường hợp này, bạn nên dùng + thay vì * nếu dùng regex này trên một văn bản lớn. Vì từ chapter rất thông dung, dễ tạo ra kết quả ko mong muốn

Thinh Minh Ha viết 16:35 ngày 01/10/2018

Đầu tiên nó sẽ match cái trong ngoặc trước sau đó match cái trong ngoặc kèm *. Trong trường hợp này, bạn nên dùng + thay vì * nếu dùng regex này trên một văn bản lớn. Vì từ chapter rất thông dung, dễ tạo ra kết quả ko mong muốn

Không phải. Ý em là chưa hiểu ở chỗ (\.\d)* :
\. : là biểu diễn cho dấu .
\d : là biểu diễn cho số 0 - 9
* : là khớp nhiều nhất có thể

=> Vậy sao kết quả trả về không phải là .4.5.1 (nhiều nhất có thể) , mà lại chỉ là .1 thôi

Thinh Minh Ha viết 16:47 ngày 01/10/2018

à, em hiểu rồi, dấu * bên ngoài cặp ngoặc () nên không tính trong Group

====================================

Nhưng mà thế cũng không phải, nếu khớp trong group (\.\d) thì kết quả trả về phải là .4 chứ ạ

Khoa Nguyen viết 16:36 ngày 01/10/2018

String.prototype.match sẽ khớp với giá trị cuối cùng, không phải giá trị đầu tiên

Thinh Minh Ha viết 16:35 ngày 01/10/2018

String.prototype.match sẽ khớp với giá trị cuối cùng, không phải giá trị đầu tiên

Nhưng mà , em thử ví dụ thế này:

var str = 'For more information, see Chapter 3.4.5.1';
var re = /\.\d/i;
var found = str.match(re);
document.write(found);

Kết quả trả về vẫn là .4 đó thôi.

Trong cái anh đưa ra String.prototype.match thì cái prototype là gì đó ạ ???

viết 16:44 ngày 01/10/2018

trên trang regex101 nó có giải thích cặn kẽ luôn mà:

A repeated capturing group will only capture the last iteration. Put a capturing group around the repeated group to capture all iterations or use a non-capturing group instead if you’re not interested in the data

(\.\d) thì bạn chỉ capture 1 dấu . và 1 chữ số => là .4, .5, hoặc .1, và nó cũng nói rõ là với repeated capturing group nghĩa là (…)+ hay (…)* có nhiều cái match, nó sẽ lấy cái cuối cùng là .1. Cái ví dụ của bạn ko phải là repeated capturing group nên nó trả về cái đầu tiên nó tìm thấy là .4. Nếu sửa lại là (\.\d)+ thì nó sẽ trả về group 1 là .1 là cái cuối cùng.

thêm dấu () bao quanh dấu * và cái group kia nữa là được:
(chapter \d+((\.\d)*))

Full match	26-41	`Chapter 3.4.5.1`
Group 1.	n/a	`Chapter 3.4.5.1`
Group 2.	n/a	`.4.5.1`
Group 3.	n/a	`.1`

lỡ có “chapter 1.12” thì (\.\d) chỉ lấy có 1.1 chữ ko lấy 1.12 @_@ thêm dấu + vào nữa cho đủ: (\.\d+)

nếu bạn ko cần cái group 3 kia thì thêm ?: vào trong (\.\d), nó sẽ ko capture group 3 nữa: (?:\.\d)

Thinh Minh Ha viết 16:35 ngày 01/10/2018

Mọi người ơi, Giờ mình muốn kiểm tra 1 chuỗi chỉ được phép chứa các chữ cái và chữ số và Chuỗi đó phải chứa ít nhất 1 ký tự thường, 1 ký tự hoa và 1 chữ số.
Mình có viết biểu thức chính quy thế này:

^([a-z]+[A-Z]+\d+|[A-Z]+[a-z]+\d+|\d+[A-Z]+[a-z]+)$

Tuy nhiên mình thấy nó hơi dài vì lại phải đổi chỗ 3 cái cho nhau.

Không biết có cách nào hay và ngắn gọn hơn không ạ

HK boy viết 16:34 ngày 01/10/2018

Bạn viết hàm kiểm tra dựa vào việc đếm số lượng của từng loại. Trường hợp này không cần dùng regex cũng được.

viết 16:35 ngày 01/10/2018

nghe giống password:

stackoverflow.com
Swapnil Tatkondawar

Regex for password must contain at least eight characters, at least one number and both lower and uppercase letters and special characters

javascript, asp.net, regex
asked by Swapnil Tatkondawar on 09:42AM - 26 Oct 13

gần như copy thẳng từ answer luôn @_@
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)[a-zA-Z\d]+$

Tâm Ninja viết 16:35 ngày 01/10/2018

/chapter [.?\d]+/gi

Biểu thức này không vượt qua case chapter 1.22222222.222222 rồi. /(chapter \d+(\.\d)*)/i là 1 số theo sau 1 kí tự chấm “.”.

Thinh Minh Ha viết 16:34 ngày 01/10/2018

nghe giống password:

stackoverflow.com

Regex for password must contain at least eight characters, at least one number and both lower and uppercase letters and special characters

javascript, asp.net, regex

asked by

user2442653

on 09:42AM - 26 Oct 13

gần như copy thẳng từ answer luôn @_@
^(?=.[a-z])(?=.[A-Z])(?=.*\d)[a-zA-Z\d]+$

Cám ơn bạn nhiều ạ :::::::::::::::

Khoa Nguyen viết 16:36 ngày 01/10/2018

Bạn chắc chứ ?

Khoa Nguyen viết 16:40 ngày 01/10/2018

Đừng giới hạn password như vậy. Please

https://blog.codinghorror.com/password-rules-are-bullshit/

Thinh Minh Ha viết 16:41 ngày 01/10/2018

^(?=.[a-z])(?=.[A-Z])(?=.*\d)[a-zA-Z\d]+$

Cho mình hỏi :

Ký hiệu ?= nó dùng để khớp nếu theo sau nó là một ký tự được ấn định trước, ví dụ x(?=y) thì x sẽ được khớp nếu nó được theo sau bởi y, nhưng trong trường hợp này ở trước ?= trước dấu ( không có ký tự gì cả (tức là trường hợp này bị khuyết x) , thì mình hiểu nó thế nào ạ ???

Cám ơn mọi người !

viết 16:39 ngày 01/10/2018

“chapter .1” nó match, hem được rồi

đổi thành [\d.?] chắc được? edit: ko được luôn @_@

chapter 1…1 nó cũng match nữa

Bài liên quan
0