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

Liên hệ QC

HeSanbi

Nam Nhân✨Hiếu Lễ Nghĩa Trí Tín✨
Tham gia
24/2/13
Bài viết
2,670
Được thích
4,170
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 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:
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


--------------------------------------------------------------------------------------------------------------------------
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 trước khớp mẫu phí sau.​
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.​
+ 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à 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:​
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 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)
 
Lần chỉnh sửa cuối:
Web KT

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

Back
Top Bottom