Các tính năng biểu thức chính quy sắp ra mắt

ES2015 đã giới thiệu nhiều tính năng mới cho ngôn ngữ JavaScript, bao gồm cả những điểm cải tiến đáng kể đối với cú pháp biểu thức chính quy bằng cờ Unicode (/u) và cờ cố định (/y). Nhưng kể từ đó, quá trình phát triển vẫn chưa dừng lại. Trong quá trình cộng tác chặt chẽ với các thành viên khác tại TC39 (cơ quan tiêu chuẩn ECMAScript), nhóm V8 đã đề xuất và đồng thiết kế một số tính năng mới để biểu thức thông thường trở nên mạnh mẽ hơn nữa.

Các tính năng này hiện đang được đề xuất đưa vào quy cách JavaScript. Mặc dù chưa được chấp nhận đầy đủ, nhưng các đề xuất này đã ở Giai đoạn 3 trong quy trình của TC39. Chúng tôi đã triển khai các tính năng này bằng một cờ (xem bên dưới) để có thể cung cấp ý kiến phản hồi kịp thời về thiết kế và cách triển khai cho các tác giả đề xuất tương ứng trước khi hoàn tất thông số kỹ thuật.

Bài đăng trên blog này sẽ cho bạn thấy trước về tương lai thú vị này. Nếu bạn muốn làm theo các ví dụ sắp tới, hãy bật các tính năng thử nghiệm của JavaScript tại chrome://flags/#enable-javascript-harmony.

Ảnh chụp được đặt tên

Biểu thức chính quy có thể chứa các phần được gọi là phần thu thập (hoặc nhóm), có thể thu thập một phần văn bản đã so khớp. Cho đến nay, nhà phát triển chỉ có thể tham chiếu đến các bản ghi này theo chỉ mục của chúng, được xác định theo vị trí của bản ghi trong mẫu.

const pattern = /(\d{4})-(\d{2})-(\d{2})/u;
const result = pattern.exec('2017-07-10');
// result[0] === '2017-07-10'
// result[1] === '2017'
// result[2] === '07'
// result[3] === '10'

Nhưng biểu thức chính quy vốn đã nổi tiếng là khó đọc, viết và duy trì, đồng thời các tệp tham chiếu số có thể làm phức tạp thêm. Ví dụ: trong các mẫu dài hơn, bạn có thể gặp khó khăn khi xác định chỉ mục của một lần chụp cụ thể:

/(?:(.)(.(?<=[^(])(.)))/  // Index of the last capture?

Tệ hơn nữa, các thay đổi đối với một mẫu có thể làm thay đổi chỉ mục của tất cả các bản ghi hiện có:

/(a)(b)(c)\3\2\1/     // A few simple numbered backreferences.
/(.)(a)(b)(c)\4\3\2/  // All need to be updated.

Tính năng sắp ra mắt là bản ghi có tên sẽ giúp giảm thiểu những vấn đề này bằng cách cho phép nhà phát triển gán tên cho bản ghi. Cú pháp tương tự như Perl, Java, .Net và Ruby:

const pattern = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
const result = pattern.exec('2017-07-10');
// result.groups.year === '2017'
// result.groups.month === '07'
// result.groups.day === '10'

Bạn cũng có thể tham chiếu đến các cụm từ tìm nạp được đặt tên bằng tham chiếu ngược được đặt tên và thông qua String.prototype.replace:

// Named backreferences.
/(?<LowerCaseX>x)y\k<LowerCaseX>/.test('xyx');  // true

// String replacement.
const pattern = /(?<fst>a)(?<snd>b)/;
'ab'.replace(pattern, '$<snd>$<fst>');                              // 'ba'
'ab'.replace(pattern, (m, p1, p2, o, s, {fst, snd}) => fst + snd);  // 'ba'

Bạn có thể xem toàn bộ thông tin chi tiết về tính năng mới này trong đề xuất quy cách.

Cờ dotAll

Theo mặc định, nguyên tử . trong biểu thức chính quy khớp với mọi ký tự ngoại trừ dấu ngắt dòng:

/foo.bar/u.test('foo\nbar');   // false

Đề xuất giới thiệu chế độ dotAll, được bật thông qua cờ /s. Ở chế độ dotAll, . cũng khớp với dấu ngắt dòng.

/foo.bar/su.test('foo\nbar');  // true

Bạn có thể xem toàn bộ thông tin chi tiết về tính năng mới này trong đề xuất quy cách.

T escape thuộc tính Unicode

Với tính năng nhận biết Unicode được giới thiệu trong ES2015, đột nhiên có nhiều ký tự khác có thể được coi là số, ví dụ như chữ số 1 trong vòng tròn: ①; hoặc được coi là ký tự từ, ví dụ như ký tự tiếng Trung cho tuyết: 雪.

Cả hai giá trị này đều không thể so khớp với \d hoặc \w. Việc thay đổi ý nghĩa của các ký hiệu viết tắt này sẽ phá vỡ các mẫu biểu thức chính quy hiện có.

Thay vào đó, chúng tôi sẽ ra mắt các trình tự thoát thuộc tính mới. Xin lưu ý rằng các biểu thức này chỉ dành cho biểu thức chính quy nhận biết Unicode được biểu thị bằng cờ /u.

/\p{Number}/u.test('①');      // true
/\p{Alphabetic}/u.test('雪');  // true

Bạn có thể so khớp hàm nghịch đảo bằng \P.

/\P{Number}/u.test('①');      // false
/\P{Alphabetic}/u.test('雪');  // false

Tập đoàn Unicode xác định nhiều thuộc tính khác, chẳng hạn như đối với các ký hiệu toán học hoặc ký tự Hiragana của Nhật Bản:

/^\p{Math}+$/u.test('∛∞∉');                            // true
/^\p{Script_Extensions=Hiragana}+$/u.test('ひらがな');  // true

Bạn có thể xem danh sách đầy đủ các lớp thuộc tính Unicode được hỗ trợ trong đề xuất quy cách hiện tại. Để biết thêm ví dụ, hãy xem bài viết cung cấp thông tin này.

Xác nhận xem lại

Xác nhận xem trước đã là một phần của cú pháp biểu thức chính quy của JavaScript từ đầu. Cuối cùng, đối tác của chúng, các câu nhận định xem trước, cũng sẽ được ra mắt. Một số bạn có thể nhớ rằng tính năng này đã có trong V8 từ khá lâu. Chúng tôi thậm chí còn sử dụng các câu nhận định xem trước trong phần nâng cao để triển khai cờ Unicode được chỉ định trong ES2015.

Tên này đã mô tả khá rõ ý nghĩa của nó. Phương thức này cung cấp một cách để hạn chế một mẫu chỉ khớp nếu mẫu đó đứng trước mẫu trong nhóm tìm kiếm phía sau. Phương thức này có cả phiên bản khớp và không khớp:

/(?<=\$)\d+/.exec('$1 is worth about ¥123');  // ['1']
/(?<!\$)\d+/.exec('$1 is worth about ¥123');  // ['123']

Để biết thêm thông tin chi tiết, hãy xem bài đăng trước trên blog dành riêng cho các câu nhận định xem lại và ví dụ trong các trường hợp kiểm thử V8 có liên quan.

Lời cảm ơn

Bài đăng trên blog này sẽ không hoàn chỉnh nếu không đề cập đến một số người đã nỗ lực để làm điều này: đặc biệt là những người ủng hộ ngôn ngữ Mathias Bynens, Dan Ehrenberg, Claude Pache, Brian Terlson, Thomas Wood, Gorkem Yakin và chuyên gia Irregexp Erik Corry; nhưng cũng như tất cả những người khác đã đóng góp vào quy cách ngôn ngữ và việc triển khai các tính năng này của V8.

Chúng tôi hy vọng bạn cũng hào hứng với các tính năng biểu thức chính quy mới này như chúng tôi!