VBA Nâng cao: Hướng dẫn tạo biểu thức tìm kiếm với Regular Expression (1 người xem)

Liên hệ QC

Người dùng đang xem chủ đề này

HeSanbi

Nam Nhân✨Hiếu Lễ Nghĩa Trí Tín✨
Tham gia
24/2/13
Bài viết
2,729
Được thích
4,302
Giới tính
Nam
Bài viết này sẽ hướng dẫn cho các bạn hiểu biết thêm về biểu thức chính quy (Regular Expression) trong VBA.
Giúp các bạn dễ dàng thực hiện tìm kiếm chuỗi phức tạp hơn rất nhiều so với các cách tìm kiếm thông thường.


Các bạn hãy xem, nếu như bạn có một tập dữ liệu văn bản trộn lẫn các kiểu dữ liệu như Email, số điện thoại, ... nằm lẫn lộn với nhau, để tách chúng ra thành dữ liệu có cấu trúc để làm việc với chúng. Thì các cách tách dữ liệu bằng hàm trong Excel và phương thức tìm và thay thế hỗ trợ không đủ khả năng để tách những dạng dữ liệu phức tạp khác nhau. Chính vì vậy biểu thức chính quy sẽ giúp thực hiện điều đó dễ dàng hơn. Sau đây là hướng dẫn chi tiết để các bạn có thể thực hiện cho công việc của mình.

Đồng thời, hiện tại Excel 365 đã hỗ trợ hàm thay thế sử dụng biểu thức chính quy là REGEXREPLACE, dựa vào bài hướng dẫn này các bạn cũng có thể ứng dụng vào hàm dễ dàng.


Hướng dẫn cú pháp cơ bản để đặt biểu thức chính quy


Ký hiệu định nghĩa cơ bản
\ là một ký tự bắt đầu cú pháp khi theo sau là: r, n, t, s, S, w, W, b, B, f, x## (định nghĩa Ascii 00-FF), uXXXX (định nghĩa ký tự unicode 0000-FFFF).​
\ xóa bỏ định nghĩa của cú pháp khi theo sau thành chuỗi, gồm: \, $, ^, |, ., ?, +, *, ... và các ký tự bất kỳ nhưng không phải là ký tự như ở định nghĩa 1.​
Ví dụ: \\ là xóa cú pháp chính nó, \|, \., \?, ...​
\ Khi đi với một số và trước nó có mẫu là nhóm có chỉ định vị trí thì cú pháp đó hiểu là kế thứa.​
Ví dụ: (abc)xx\1 là một mẫu có cú pháp kế thừa \1 kế thừa lại giá trị tìm được trong nhóm 1.​
| Thanh dọc hiểu là mẫu điều kiện "hoặc", mỗi mẫu của 1 điều kiện bao gồm tất cả cú pháp liên tục ngang hàng, các cú pháp nhóm sẽ giới hạn mẫu điều kiện nằm trong chúng.​
Ví dụ: hello|hi lấy chuỗi kí tự hello hoặc chuỗi hi.​
Ví dụ: abc(hello|hi)ef lấy chuỗi abc và nhóm (hello hoặc hi) và chuỗi ef.​
Cú pháp định nghĩa xác định ký tự
. Dấu chấm hiểu là chụp 1 ký tự bất kỳ không bao gồm ký tự xuống dòng
[ ] Đối sánh bất kỳ ký tự đơn nào giữa các dấu ngoặc [ ]. Ví dụ: [AaSs] chụp 1 ký tự là A hoặc a, S, s​
Nếu muốn nhập chính ký hiệu này vào trong nó thì nhập là [[] tìm [ , nhập là [][] thì tìm dấu [ hoặc ], hoặc [\[]​
[^ ] Chụp 1 ký tự không chứa các ký tự. Ví dụ: [^AaSs] chụp 1 ký tự khác A và a, S, s​
[-] Chụp từ ký tự cho đến ký tự. Ví dụ: [A-Za-z0-9]+ chụp các ký tự A đến Z, a đến z, 0 đến 9 với một hoặc nhiều lần.​
Nếu muốn nhập chính ký hiệu gạch ngang (-) thì đặt sau cùng, ví dụ [A-] thì tìm ký tự A hoặc dấu -​
\s Chụp 1 ký tự khoảng trắng bao gồm các ký tự: cách, trở về dòng trên, xuống dòng, tab, tab đứng và feed​
\S Chụp 1 ký tự không phải ký tự khoảng trắng.​
\w Chụp 1 ký tự và số và dấu gạch dưới.​
\W Chụp 1 Ký tự không phải Ký tự chữ và số và dấu gạch dưới.​
\d Chụp 1 ký tự là số.​
\D Chụp 1 ký tự không thuộc số.​
\t Chụp 1 ký tự Tab.​
\r Chụp 1 ký tự trở lại dòng trên (Charcode: 13).​
\n Chụp 1 ký tự xuống dòng (Charcode: 10).​
\f feed - ký tự nguồn cấp dữ liệu.​
\uXXXX Chụp 1 ký tự Unicode (định nghĩa ký tự unicode hexadecimal từ 0000-FFFF).​
Ví dụ: \u1EA5 lấy ký tự "ấ", lấy ký tự từ Z đến ấ thì biểu thức là [Z-\u1EA5].
\xXX Chụp 1 ký tự ASCII (định nghĩa Ascii từ hexadecimal 00-FF). Ví dụ: \x41 ký tự A.​
Cú pháp định nghĩa xác định không gian liền kề giữa các kiểu ký tự
Ký tự bao gồm có chữ số, ký tự chữ, ký tự dấu, ký tự phân tách, \b và \B hiểu là định nghĩa ràng buộc liền kề của một ký tự.
\b Đến ký tự phân tách. Ví dụ: a\b hiểu là chụp ký tự a nếu theo sau a ký tự phân tách.​
\B Không đến ký tự phân tách, hiểu là ngược lại ở trên.​
Ký hiệu chỉ định số lượng
Cú pháp chỉ định số lượng của mẫu, luôn luôn nằm sau mẫu.​
? Không hoặc lấy một lần của cú pháp.​
Nếu dấu ? nằm sau một ký hiệu xác định nhiều số lượng, thì bắt buộc theo sau nó phải có mẫu, thì hiểu là chỉ tìm đến khi gặp 1 khớp mẫu phía sau thì dừng tìm.​
Ví dụ: .+?b , tìm ký các tự bất kỳ cho đến khi gặp khớp mẫu là b.​
Nếu không có dấu ? thì tìm bỏ qua các vị trí khớp mẫu b, cho đến khi tìm thấy khớp mẫu b cuối cùng thì dừng.​
+ Khả năng khớp mẫu là một hoặc nhiều lần nhất có thể, kết hợp với dấu ? thì hiểu là tìm cho đến khi gặp mẫu liền sau thì dừng lại.​
* Như cú pháp + nhưng khả năng khớp mẫu bắt đầu từ 0.​
{9} Giới hạn số lượng khớp mẫu là 9 lần. Ví dụ: a{9} lấy 9 ký tự a liên tục.​
{2,9} Khả năng khớp mẫu từ 2 đến 9 lần. Ví dụ: a{2,4} lấy 2 đến 4 ký tự a liên tục.​
{3,} Khả năng khớp mẫu từ 3 lần trở lên. Ví dụ: a{4,} lấy a từ 4 ký tự trở lên.​
{0,12} Khả năng khớp mẫu từ 0 đến 12 lần. Ví dụ: a{0,12}.​
Ký hiệu buộc phải tìm khớp từ đầu hoặc ở cuối văn bản
^ Bắt đầu phải là chuỗi khớp với biểu thức. Ví dụ: ^hello.* bắt đầu bằng hello và chuỗi bất kỳ.​
$ Kết thúc phải là chuỗi trước nó. Ví dụ: .+a$ chụp bất kỳ chuỗi nào cuối phải là các ký tự a.​
Nhóm trong biểu thức chính quy:
Nhóm được định nghĩa là biểu thức nằm trong cặp ngoặc tròn ( và ).​
Trong lớp Scipting.RegExp chỉ hỗ trợ 4 dạng nhóm sau đây:​
1. ( ) Nhóm: chụp khớp biểu thức có chỉ định vị trí thứ tự nhóm.​
Ví dụ: chụp ký tự a và b thì biểu thức nhóm là (a)(b) thì hiểu a nằm trong là nhóm 1, b nằm trong nhóm 2​
Vị trí của nhóm có 2 chức năng:​
+ Dùng để thay thế nhưng giữ lại nhóm đó, sử dụng ký tự đô-la là $ và 1 số để chỉ định vị trí nhóm trong chuỗi thay thế:​
Ví dụ: trong chuỗi "abce" tìm "(a)bc" thay thế thành rỗng, nhưng giữ lại nhóm 1, thì chuỗi thay thế là "$1"​
+ Dùng để kế thừa, sử dụng dấu \ và số trong biểu thức:​
Ví dụ: trong chuỗi "abbce" tìm "(a)(?=b\1c)" hiểu là tìm ký tự a và theo sau phải là b và kế thừa \1 (a là nhóm 1) và ký tự c.​
2. (?: ) Nhóm: Chụp nhưng không chỉ định vị trí của nhóm.​
Ví dụ: (a)(?:b)(c) chụp ký tự a và b và c, hiểu a là nhóm 1, c là nhóm 2​
3. (?= ) Nhóm: Nhóm liền kề sau nhưng không chụp. Luôn luôn cần có mẫu phía trước nó.​
Ví dụ: a(?=b) chụp ký tự a, nếu theo sau a là ký tự b.​
4. (?! ) Nhóm: Nhóm tìm không khớp không chỉ định vị trí nhóm.​
Ví dụ: (?!hello) hiểu là chụp 5 ký tự bất kỳ nhưng phải khác chuỗi ký tự hello​
Ký hiệu kế thừa \ và 1 số
Ký hiệu kế thừa bắt buộc trước nó phải có mẫu là nhóm có chỉ định vị trí, kế thừa có nghĩa là khi mẫu nhóm đó đã xác định được giá trị, thì sẽ kế thừa lại giá trị đó (không phải là kế thừa lại cả mẫu nhóm đó).​
Ví dụ: với mẫu (\wx)(?=b\1c) Nếu nhóm 1 tìm được ký tự bất kỳ ở đây cho là d và x​
thì theo sau phải là bdxc dx là kế thừa từ nhóm 1. thì chuỗi tìm kiếm bắt buộc chứa giá trị là dxbdxc
Cách xác định vị trí nhóm khi lòng các cú pháp nhóm vào nhau hiểu như sau:
Nhóm nào nằm ngoài cùng thì có thứ tự ưu tiên, nếu nhóm có các nhóm lòng trong nhau, thì ưu tiên đếm trước.​
Rồi mới đếm các nhóm ngang hàng.​
Ví dụ mẫu là: ((a(b)c)(?:d(e)f)(g))
Vì có cặp ngoặc ngoài cùng nên hiểu cả biểu thức là nhóm 1​
Trong nhóm có nhóm thì đếm theo thứ tự + thêm 1, nên abc thuộc nhóm 2.​
Trong nhóm 2 có nhóm con là b thì b này thuộc vị trí thứ 3. Trong nhóm 3 không còn. Thì trở ra khỏi nhóm để đếm tiếp tục.​
Vì nhóm của def có cú pháp ?: không xem là có vị trí nên không đếm. Nhưng trong nhóm của def có nhóm con, nên e là thuộc nhóm thứ 4.​
Và g là nhóm thứ 5 cuối cùng.​
Thay thế linh hoạt:
Ký hiệu $số chỉ định vị trí nhóm trong chuỗi cần thay thế để giữ nhóm đó sau khi thay thế chuỗi mới.​
(Có một số ngôn ngữ và trình soạn thảo mã như Notepad++ thì dấu \ sẽ chỉ định vị trí thay cho $)​
Dựa vào ví dụ trên ta thay thế giữ nhóm và dịch vị trí như sau: đưa nhóm 1 đến vị trí thứ 2, đưa vị trí thứ 2 đến vị trí thứ 3 và vị trí thứ 3 về đầu, đồng thời chèn ký tự bất kì xen giữ, thì ta có mẫu thay thế là: "$3xxx$1xxx$2", mã VBA sẽ là:​

Re.Pattern = "((a(b)c)(?:d(e)f)(g))"
Text = RE.Replace("abcdefg","$3xxx$1xxx$2")
Trong Excel365:​
=REGEXREPLACE("Chuỗi","((a(b)c)(?:d(e)f)(g))","$3xxx$1xxx$2")
Phần biểu thức chính quy có trong các ngôn ngữ hiện đại, không hỗ trợ trong VBA
Các cú pháp biểu thức chính quy có trong các ngôn ngữ như: Python, PHP, java, javascript, perl, R, Rupy, C#, C/C++, ...​
(?<= ) tìm xét biểu thức phía trước có khớp với mẫu, hiểu là cú pháp này nằm ở phía trước của mẫu.​
(?<! ) tìm xét biểu thức phía trước phải không khớp với mẫu, hiểu là cú pháp này nằm ở phía trước của mẫu.​
(?R) hoặc (?0) Đệ quy trong biểu thức chính quy. Đệ quy có nghĩa là tìm mẫu lòng trong mẫu đó nhiều lần​
Ví dụ: chuỗi "Sum(Sum(Sum(Sum()))+Sum(Sum(Sum())))", các bạn sẽ thấy các cặp ngoặc nằm trong nhau, để tìm được các cặp lòng trong nhiều và nhiều lần nữa, thì cần đến Đệ quy.​
(?(điều kiện)else|then)
(?P<tên> ) Đặt tên cho mẫu, sau khi tìm được mẫu, thì mẫu đó được gán theo tên. Để truy cập lại.​

Các lỗi thường gặp


1. Nhập ký tự cú pháp như [, (, ), \, ?, +, * đơn lẻ để hiểu chúng là ký tự thường là sai, hãy thêm dấu \ phía trước chúng để hiểu chúng là ký tự thường, còn không phải nhập đúng cú pháp biểu thức.
2. Dễ nhầm ký tự xuống dòng newLine, vì vậy nên luôn luôn cần sử dụng \r?\n​
3. Gây ra vòng lặp tính toán vô tận không thoát ra được khi sử dụng cú pháp số lượng nhiều lần như + và * không hợp lý.​
Ví dụ: (((.*?)*?)*?)*?​


Hướng dẫn lưu trữ biểu thức tự tạo

Các bạn cần ghi nhớ và lưu trữ các biểu thức do bạn sáng tạo, hoặc tìm được qua mạng, để dễ nhớ và truy cập lại nhanh chóng.
Hãy lưu trữ biểu thức vào bảng Excel, mỗi biểu thức thực hiện với một chuỗi có cấu trúc nào đó đều có tên, chính vì vậy hãy đặt tên để dễ nhớ cho biểu thức. Mỗi mẫu tìm kiếm đều cần có các ví dụ cụ thể nhiều trường hợp xảy ra, cần có phép thử đúng sai và kết quả cuối cùng.

Có thể tạo bảng lưu trữ như sau:

Chủ đềKiểu dữ liệuBiểu thứcVí dụPhép thửKết quảThay thế
Tìm sốSố[-+]?\d+(?:\.\d+)?ABC -2004TRUE-2004Trống
Tìm chuỗiKý tự\w+Hello 2024TRUEHello Trống

Các phương thức trong lớp Biểu thức chính quy dành cho VBA


Nếu khởi tạo một đối tượng đại diện chính của lớp là RE như sau:
Set RE = CreateObject("VBScript.RegExp")​

Đặt tùy chọn để xác định cách tìm kiếm dữ liệu:
RE.Global = TRUELấy 1 hoặc tất cả khớp mẫu xảy ra.
RE.MultiLine = TRUEKhớp mẫu xảy ra trên các ngắt dòng.
RE.IgnoreCase = TRUEBỏ phân biệt Hoa Thường
RE.Pattern = "biểu thức"Phương thức nhận mẫu sẽ sử dụng để đối sánh với chuỗi

Các phương thức của lớp
bool = RE.test("chuỗi")Kiểm tra thử xem có khớp mẫu không
Text = RE.Replace("Chuỗi tìm kiếm","chuỗi thay thế")Thay thế khớp mẫu thành chuỗi mới
Text = RE.Replace("Chuỗi","$1")Thay thế giữ nhóm bằng $ và số thứ tự nhóm
Set Matches = RE.Execute("chuỗi")Lấy các khớp mẫu (Matches)
Matches(0)Lấy 1 Item của Matches
Matches.CountĐếm item trong Matches
Matches(0).FirstIndexVị trí bắt đầu của khớp mẫu
Matches(0).LengthĐộ dài của khớp mẫu
Matches(0).SubMatchesCác nhóm trong mỗi khớp mẫu
Matches(0).SubMatches.CountĐếm item trong SubMatches
Matches(0).SubMatches(0)Xuất 1 giá trị của SubMatches

Phần thực hành với biểu thức chính quy

Sau khi tìm hiểu xong phần cơ bản ở trên thì các bạn có thể bước vào phần thực hành này một cách dễ dàng để hiểu được các mã ví dụ về cách tìm kiếm, thay thế với các văn bản phức tạp mà bạn biết.

Trước hết, các bạn nên biết về cách khởi tạo lớp Regular Expression trong VBA
Khi viết mã trong VBA, có 2 cách khởi tạo lớp thư viện cho dự án
1. Chọn thư viện trong danh sách các thư viện đang chạy mặc định trong máy tính. có tên sau:​
Microsoft VBScript Regular Expressions 5.5
1736404518346.png
2. Khởi tạo thư viện với phương thức CreateObject, mà không cần tham chiếu sớm thư viện.​
Set RE = CreateObject("VBScript.RegExp")​

Tạo vài hàm tìm kiếm cơ bản chung hay dùng

Hàm khởi tạo lớp:

JavaScript:
Private Function glbRegex(Optional bGlobal As Boolean = True, Optional ignoreCase As Boolean = True, Optional Multiline As Boolean = True) As Object
  Set glbRegex = CreateObject("VBScript.RegExp")
  With glbRegex: .Global = bGlobal: .ignoreCase = ignoreCase: .Multiline = Multiline: End With
End Function

Hàm tìm kiếm:
JavaScript:
Function TestRE(ByVal Expression$, Optional compare As Boolean) As String
  On Error Resume Next
  With CreateObject("VBScript.RegExp")
    .Global = True: .IgnoreCase = compare: .MultiLine = False
    .pattern = Find
    TestRE = .test(Expression)
  End With
  Err.Clear
End Function
Hàm thay thế:
JavaScript:
Function RegExReplace(ByVal Expression$, ByVal Find$, ByVal Replace As String, Optional IgnoreCase As Boolean) As String
  On Error Resume Next
  With CreateObject("VBScript.RegExp")
    .Global = True: .IgnoreCase = IgnoreCase: .MultiLine = False
    .pattern = Find
    RegExReplace = .Replace(Expression, Replace)
  End With
  Err.Clear
End Function

Hướng dẫn thực hành tại các bài viết bên dưới:

----------------------------------------------------------
Add-in dưới link này của tôi có hỗ trợ sử dụng biểu thức chính quy để tìm và thay thế trong Excel rất linh hoạt, các bạn có thể tham khảo thêm để học và sử dụng biểu thức chính quy.
https://giaiphapexcel.com/diendan/threads/165337/

(Sẽ còn tiếp cập nhật các đoạn mã ví dụ để học tập từ cơ bản đến nâng cao)
 

File đính kèm

Lần chỉnh sửa cuối:
Giải pháp
Cập nhật hướng dẫn phần thực hành
(Đã thêm tập tin thực hành trên bài viết chính #1)

Các ví dụ điểm hình về khả năng của Biểu thức chính quy có thể làm được

Chủ đề Kiểu dữ liệu Biểu thức mẫu
Tìm sốSố[-+]?\d+(?:\.\d+(?:E\+\d+)?)?
Tìm chuỗiKý tự\w+
Tìm khớp cả chuỗi ^abc$
Loại bỏ số trùng lặp (\d)(?=.+?\1)
...
Bài viết này sẽ hướng dẫn cho các bạn hiểu biết thêm về biểu thức chính quy (Regular Expression) trong VBA.
Giúp các bạn dễ dàng thực hiện tìm kiếm chuỗi phức tạp hơn rất nhiều so với các cách tìm kiếm thông thường.


Các bạn hãy xem, nếu như bạn có một tập dữ liệu văn bản lôn xộn như Email, số điện thoại, ... nằm lẫn lộn với nhau, để tách chúng ra thành dữ liệu có cấu trúc để làm việc với chúng. Thì các cách tách dữ liệu bằng hàm trong Excel và phương thức tìm và thay thế hỗ trợ không đủ khả năng để tách những dạng dữ liệu phức tạp khác nhau. Chính vì vậy biểu thức chính quy sẽ giúp thực hiện điều đó dễ dàng hơn. Sau đây là hướng dẫn chi tiết để các bạn có thể thực hiện cho công việc của mình.

Đồng thời, hiện tại Excel 365 đã hỗ trợ hàm thay thế sử dụng biểu thức chính quy là REGEXREPLACE, dựa vào bài hướng dẫn này các bạn cũng có thể ứng dụng vào hàm dễ dàng.

--------------------------------------------------------------------------------------------------------------------------
Các phương thức trong lớp Biểu thức chính quy dành cho VBA:

Nếu khởi tạo một đối tượng đại diện chính của lớp là RE như sau:


Đặt tùy chọn để xác định cách tìm kiếm dữ liệu:
RE.Global = TRUELấy 1 hoặc tất cả khớp mẫu xảy ra.
RE.MultiLine = TRUEKhớp mẫu xảy ra trên các ngắt dòng.
RE.IgnoreCase = TRUEBỏ phân biệt Hoa Thường
RE.Pattern = "biểu thức"Phương thức nhận mẫu sẽ sử dụng để đối sánh với chuỗi


Các phương thức của lớp
bool = RE.test("chuỗi")Kiểm tra thử xem có khớp mẫu không
Text = RE.Replace("Chuỗi tìm kiếm","chuỗi thay thế")Thay thế khớp mẫu thành chuỗi mới
Text = RE.Replace("Chuỗi","$1")Thay thế giữ nhóm bằng $ và số thứ tự nhóm
Set Matches = RE.Execute("chuỗi")Lấy các khớp mẫu (Matches)
Matches(0)Lấy 1 Item của Matches
Matches.CountĐếm item trong Matches
Matches(0).FirstIndexVị trí bắt đầu của khớp mẫu
Matches(0).LengthĐộ dài của khớp mẫu
Matches(0).SubMatchesCác nhóm trong mỗi khớp mẫu
Matches(0).SubMatches.CountĐếm item trong SubMatches
Matches(0).SubMatches(0)Xuất 1 giá trị của SubMatches


--------------------------------------------------------------------------------------------------------------------------
Hướng dẫn cú pháp cơ bản để đặt biểu thức chính quy
Ký hiệu định nghĩa cơ bản
\ là một ký tự bắt đầu cú pháp khi theo sau là: r, n, t, s, S, w, W, b, B, f, x## (định nghĩa Ascii 01-FF), uXXXX (định nghĩa ký tự unicode 0001-FFFF)​
\ xóa bỏ định nghĩa của cú pháp khi theo sau thành chuỗi, gồm: \, $, ^, |, ., ?, +, *, ... và các ký tự bất kỳ nhưng không phải là ký tự như ở định nghĩa 1.​
Ví dụ: \\ là xóa cú pháp chính nó, \|, \., \?, ...​
| Thanh dọc hiểu là "hoặc". Ví dụ: hello|hi lấy chuỗi kí tự hello hoặc chuỗi hi​
Cú pháp định nghĩa xác định ký tự
. Dấu chấm hiểu là chụp 1 ký tự bất kỳ không bao gồm ký tự xuống dòng
[ ] Đối sánh bất kỳ ký tự đơn nào giữa các dấu ngoặc [ ]. Ví dụ: [AaSs] chụp 1 ký tự là A hoặc a, S, s​
Nếu muốn nhập chính ký hiệu này vào trong nó thì nhập là [[] tìm [ , nhập là [][] thì tìm dấu [ hoặc ], hoặc [\[]​
[^ ] Chụp 1 ký tự không chứa các ký tự. Ví dụ: [^AaSs] chụp 1 ký tự khác A và a, S, s​
[-] Chụp từ ký tự cho đến ký tự. Ví dụ: [A-Za-z0-9]+ chụp các ký tự A đến Z, a đến z, 0 đến 9 với một hoặc nhiều lần.​
Nếu muốn nhập chính ký hiệu gạch ngang (-) thì đặt sau cùng, ví dụ [A-] thì tìm dấu A hoặc -​
\s Chụp 1 ký tự phân cách bao gồm các ký tự:​
\S Chụp 1 ký tự không phải ký tự phân cách​
\w Chụp 1 ký tự và số và dấu gạch dưới​
\W Chụp 1 Ký tự không phải Ký tự chữ và số và dấu gạch dưới​
\d Chụp 1 ký tự là số​
\D Chụp 1 ký tự không thuộc số​
\t Chụp 1 ký tự Tab​
\r Chụp 1 ký tự trở lại dòng trên (Charcode: 13)​
\n Chụp 1 ký tự xuống dòng (Charcode: 10)​
\f feed​
\uXXXX Chụp 1 ký tự Unicode (định nghĩa ký tự unicode 0001-FFFF). Ví dụ: \u1EA5 lấy ký tự "ấ", lấy ký tự từ Z đến ấ thì biểu thức là [Z-\u1EA5]
\xXX Chụp 1 ký tự ASCII (định nghĩa Ascii 01-FF). Ví dụ: \x41 ký tự A​
Cú pháp định nghĩa xác định không gian liền kề giữa các kiểu ký tự
Ký tự bao gồm có chữ số, ký tự chữ, ký tự dấu, ký tự phân tách, \b và \B hiểu là định nghĩa ràng buộc liền kề của một ký tự.
\b Đến ký tự phân tách. Ví dụ: a\b hiểu là chụp ký tự a nếu theo sau a ký tự phân tách.​
\B Không đến ký tự phân tách, hiểu là ngược lại ở trên.​
Ký hiệu chỉ định số lượng
? không hoặc lấy một lần của cú pháp.​
Nếu dấu ? nằm sau một ký hiệu xác định nhiều số lượng, thì hiểu là chỉ tìm đến khi gặp 1 khớp mẫu phía sau thì dừng tìm.​
Ví dụ: .+?b , tìm ký các tự bất kỳ cho đến khi gặp khớp mẫu là b.​
Nếu không có dấu ? thì tìm bỏ qua các vị trí khớp mẫu b, cho đến khi tìm thấy khớp mẫu b cuối cùng thì dừng.​
+ Một hoặc nhiều lần của cú pháp.​
* Không hoặc nhiều lần của cú pháp.​
{9} Giới hạn số lượng khớp mẫu là 9 lần. Ví dụ: a{9} lấy 9 ký tự a liên tục.​
{2,9} Lấy 2 đến 9 lần của cú pháp. Ví dụ: a{2,4} lấy 2 đến 4 ký tự a liên tục.​
{3,} Hiểu là tìm từ 3 lần khớp mẫu trở lên. Ví dụ: a{4,} lấy a từ 4 ký tự trở lên.​
{,12} Hiểu là tìm từ 12 lần khớp mẫu trở xuống. Ví dụ: a{,12} lấy a từ 12 ký tự trở xuống.​
Ký hiệu buộc phải tìm khớp từ đầu hoặc ở cuối văn bản
^ Bắt đầu phải là chuỗi khớp với biểu thức. Ví dụ: ^hello.* bắt đầu bằng hello và chuỗi bất kỳ.​
$ Kết thúc phải là chuỗi trước nó. Ví dụ: .+a$ chụp bất kỳ chuỗi nào cuối phải là các ký tự a.​
Nhóm trong biểu thức chính quy:
Nhóm được định nghĩa là biểu thức nằm trong cặp ngoặc tròn ( và ).​
Trong lớp Scipting.RegExp chỉ hỗ trợ 4 dạng nhóm sau đây:​
1. ( ) Nhóm: chụp khớp biểu thức có chỉ định vị trí thứ tự nhóm.​
Ví dụ: chụp ký tự a và b thì biểu thức nhóm là (a)(b) thì hiểu a nằm trong là nhóm 1, b nằm trong nhóm 2​
Vị trí của nhóm có 2 chức năng:​
+ Dùng để thay thế nhưng giữ lại nhóm đó, sử dụng ký tự đô-la là $ và 1 số để chỉ định vị trí nhóm trong chuỗi thay thế:​
Ví dụ: trong chuỗi "abce" tìm "(a)bc" thay thế thành rỗng, nhưng giữ lại nhóm 1, thì chuỗi thay thế là "$1"​
+ Dùng để kế thừa, sử dụng dấu \ và 1 số trong biểu thức:​
Ví dụ: trong chuỗi "abbce" tìm "(a)(?=b\1c)" hiểu là tìm ký tự a và theo sau phải là b và \1 (a là nhóm 1) và ký tự c​
2. (?: ) Nhóm: Chụp nhưng không chỉ định vị trí của nhóm.​
Ví dụ: (a)(?:b)(c) chụp ký tự a và b và c, hiểu a là nhóm 1, c là nhóm 2​
3. (?= ) Nhóm: Nhóm liền kề sau nhưng không chụp.​
Ví dụ: a(?=b) chụp ký tự a, nếu theo sau a là ký tự b.​
4. (?! ) Nhóm: Nhóm tìm không khớp không chỉ định vị trí nhóm.​
Ví dụ: (?!hello) hiểu là chụp 5 ký tự bất kỳ nhưng phải khác chuỗi ký tự hello​
Phần biểu thức chính quy có trong các ngôn ngữ hiện đại, không hỗ trợ trong VBA
Các cú pháp biểu thức chính quy có trong các ngôn ngữ như: Python, PHP, java, javascript, perl, R, Rupy, C#, C/C++, ...​
(?<= ) tìm xét biểu thức phía trước có khớp với mẫu, hiểu là cú pháp này nằm ở phía trước của mẫu.​
(?<! ) tìm xét biểu thức phía trước có không khớp với mẫu, hiểu là cú pháp này nằm ở phía trước của mẫu.​
(?R) hoặc (?0) Đệ quy trong biểu thức chính quy. Đệ quy có nghĩa là tìm mẫu lòng trong mẫu đó nhiều lần​
Ví dụ: chuỗi "Sum(Sum(Sum(Sum()))+Sum(Sum(Sum())))", các bạn sẽ thấy các cặp ngoặc nằm trong nhau, để tìm được các cặp lòng trong nhiều và nhiều lần nữa, thì cần đến Đệ quy.​
(?(điều kiện)else|then)
(?P<tên> ) Đặt tên cho mẫu, sau khi tìm được mẫu, thì mẫu đó được gán theo tên. Để truy cập lại.​

--------------------------------------------------------------------------------------------------------------------------
Hướng dẫn lưu trữ biểu thức tự tạo

Các bạn cần ghi nhớ và lưu trữ các biểu thức do bạn sáng tạo, hoặc tìm được qua mạng, để dễ nhớ và truy cập lại nhanh chóng.
Hãy lưu trữ biểu thức vào bảng Excel, mỗi biểu thức thực hiện với một chuỗi có cấu trúc nào đó đều có tên, chính vì vậy hãy đặt tên để dễ nhớ cho biểu thức.
Mỗi mẫu tìm kiếm đều cần có các ví dụ cụ thể nhiều trường hợp xảy ra, cần có phép thử đúng sai và kết quả cuối cùng.
Có thể tạo bảng lưu trữ như sau:

Chủ đềkiểu dữ liệuBiểu thứcVí dụPhép thửKết quả
Tìm sốSố[-+]?\d+(?:\.\d+)?ABC -2004TRUE-2004
Tìm chuỗiKý tự\w+Hello 2024TRUEHello


--------------------------------------------------------------------------------------------------------------------------
Phần thực hành với biểu thức chính quy
Sau khi tìm hiểu xong phần cơ bản ở trên thì các bạn có thể bước vào phần thực hành này một cách dễ dàng để hiểu được các mã ví dụ về cách tìm kiếm, thay thế với các văn bản phức tạp mà bạn biết.

Trước hết, các bạn nên biết về cách khởi tạo lớp Regular Expression trong VBA
Khi viết mã trong VBA, có 2 cách khởi tạo lớp thư viện cho dự án
1. Chọn thư viện trong danh sách các thư viện đang chạy mặc định trong máy tính. có tên sau:​

2. Khởi tạo thư viện với phương thức CreateObject, mà không cần tham chiếu sớm thư viện.​


Tạo vài hàm tìm kiếm cơ bản chung hay dùng:

Hàm khởi tạo lớp:
JavaScript:
Private Function glbRegex(Optional bGlobal As Boolean = True, Optional ignoreCase As Boolean = True, Optional Multiline As Boolean = True) As Object
  Set glbRegex = CreateObject("VBScript.RegExp")
  With glbRegex: .Global = bGlobal: .ignoreCase = ignoreCase: .Multiline = Multiline: End With
End Function

Hàm tìm kiếm:
JavaScript:
Function TestRE(ByVal Expression$, Optional compare As Boolean) As String
  On Error Resume Next
  With CreateObject("VBScript.RegExp")
    .Global = True: .IgnoreCase = compare: .MultiLine = False
    .pattern = Find
    TestRE = .test(Expression)
  End With
  Err.Clear
End Function
Hàm thay thế:
JavaScript:
Function ReplaceRE(ByVal Expression$, ByVal Find$, ByVal Replace As String, Optional compare As Boolean) As String
  On Error Resume Next
  With CreateObject("VBScript.RegExp")
    .Global = True: .IgnoreCase = compare: .MultiLine = False
    .pattern = Find
    Expression = .Replace(Expression, Replace)
  End With
  ReplaceRE = Expression
  Err.Clear
End Function


------------------------------------------------------------------------------------------
Add-in dưới link này của tôi có hỗ trợ sử dụng biểu thức chính quy để tìm và thay thế trong Excel rất linh hoạt, các bạn có thể tham khảo thêm để học và sử dụng biểu thức chính quy.
https://giaiphapexcel.com/diendan/threads/165337/

(Sẽ còn tiếp cập nhật các đoạn mã ví dụ để học tập từ cơ bản đến nâng cao)
Vài năm nữa VBScript bị xóa khỏi Windows rồi, chưa biết lấy cái gì để thay thế đây.
 
Upvote 0
Vài năm nữa VBScript bị xóa khỏi Windows rồi, chưa biết lấy cái gì để thay thế đây.
Khi đó tôi chắc chắn sẽ làm ra cái ActivexX DLL giống hệt như RegExp mà có thể còn thêm thắp vài thành phần cho nhiều tiện ích nữa ấy chứ. Mọi người yên tâm cài này mất đi sẽ có cái khác đáp ứng thôi.
 
Upvote 0
Microsoft đang phát triển các hàm mới sử dụng biểu thức Regular Expression: REGEXTEST, REGEXEXTRACT và REGEXREPLACE.
Chủ đề này giúp mọi người vận dụng tốt hơn các hàm mới.
 
Upvote 0
Microsoft đang phát triển các hàm mới sử dụng biểu thức Regular Expression: REGEXTEST, REGEXEXTRACT và REGEXREPLACE.
Chủ đề này giúp mọi người vận dụng tốt hơn các hàm mới.
Mấy hàm này có mặt trên Microsoft 365 cũng tương đối lâu rồi.

Mấy hàm này chỉ có trên phiên bản Insider. Chưa thấy nhập vào phiên bản thông dụng.
Tuy nhiên tôi rất có thể sai. Nếu bạn biết ngày MS cho chúng vào phiên bản thông dụng thì đăng lên đây cho mọi người cùng cập nhật kiến thức với.

MS VBScript:
Excel là chỗ hái ra tiền của MS, không phải đồ chùa (như phiên bản thấp của Google Sheets). Họ bắt buộc phải có cách hỗ trợ các hệ thống cũ.
MS Windows có it nhất hai phiên bản regex'es. Một hằm trong thư viện VBScript và một nằm trong thư viện DOT NET. Phiên bản của dot Net tốt và cập nhật hơn phiên bản kia. Trước ngày MS quyết đinh đưa VBScript và các thư viện của nó ra khỏi Windows thì họ sẽ chỉ dẫn cách dùng các thư viện thay thế.
 
Upvote 0
Cập nhật về các hàm REGEX**** của MS Excel:

Theo bài blog của Jake Amstrong đăng ngày 20/05/2024 và cập nhật bởi Linda_C (a Product Manager on the Excel team) ngày 26/08/2024 trên kênh Techcommunity của MS thì các hàm này vẫn còn lẩn quẩn trong phiên bản Insider.

https:// techcommunity.microsoft.com /blog/microsoft365insiderblog/new-regular-expression-regex-functions-in-excel/4226334

Chú: địa vị Product Manager tùy trường hợp mà đứng ngay dưới, tương đương, hay trên Project Manager.
 
Upvote 0
Khi đó tôi chắc chắn sẽ làm ra cái ActivexX DLL giống hệt như RegExp mà có thể còn thêm thắp vài thành phần cho nhiều tiện ích nữa ấy chứ. Mọi người yên tâm cài này mất đi sẽ có cái khác đáp ứng thôi.
Đa số ngôn ngữ lập trình hiện nay đều hỗ trợ Regular Expression nên việc viết lớp gói gọn cũng tương đối đơn giản.
Tôi cũng đã viết gói gọn trên .NET để dùng sau này Microsoft xóa VBScript khỏi Windows.
1737212233847.png
 
Upvote 0
Cập nhật hướng dẫn phần thực hành
(Đã thêm tập tin thực hành trên bài viết chính #1)

Các ví dụ điểm hình về khả năng của Biểu thức chính quy có thể làm được

Chủ đề Kiểu dữ liệu Biểu thức mẫu
Tìm sốSố[-+]?\d+(?:\.\d+(?:E\+\d+)?)?
Tìm chuỗiKý tự\w+
Tìm khớp cả chuỗi ^abc$
Loại bỏ số trùng lặp (\d)(?=.+?\1)
Loại bỏ ký tự trùng lặp (\w)(?=.+?\1)
Kiểm tra địa chỉ MailEmail^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4})*/$
Đường dẫn thư mục ^(?!.*[\\\/]\s+)(?!(?:.*\s|.*\.|\W+)$)(?:[a-zA-Z]:)?(?:(?:[^<>:"\|\?\*\n])+(?:\/\/|\/|\\\\|\\)?)+$
Đường dẫn URL 1 ^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)
Đường dẫn URL 2 (https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#&//=\?]*)
Đường dẫn URL 3 (?:(?:https?|ftp|ws|wss|file):\/\/)?(?:www\.|ftp\.)?(?:\([-a-zA-Z0-9+&@#\/%=~|$!:,.?_]*\)|[-a-zA-Z0-9+&@#\/%=~|$!:,.?_])*(?:\([-a-zA-Z0-9+&@#\/%=~|$!:,.?_]*\)|[a-zA-Z0-9+&@#\/%=~|$_])
IP v4IP Address^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))*$
Số điện thoại ^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$
Bỏ xuống dòng XML/HTML/XALM/SVG <!--(.*?)-->|\r?\n\s*\B
Range \$?[A-Z]{1,3}(?:\$?\d+)?(?::\$?[A-Z]{1,3}(?:\$?\d+)?)?
Hex trong VBA &H[0-9A-F]{1,16}
Octal trong VBA &O[0-7]{1,10}
Từ khóa [A-z][A-z0-9_]{255}
Xóa số đầu chuỗi ^\d+
Xóa ký tự đầu chuỗi ^\w+
Xóa số cuối chuỗi \d+$
Xóa ký tự cuối chuỗi \w+$


Xóa bất kỳ Hàm nào và Đối số nào trong một biểu thức Excel phức tạp

Tách số điện thoại hoặc chuyển đổi từ số cũ sang số mới.

Tìm và thay thế trong Excel giữ lại định dạng

Gộp giá trị ô giữ định dạng
 

File đính kèm

Upvote 0
Giải pháp
Web KT

Bài viết mới nhất

Back
Top Bottom