Thử nghiệm VBScript RegExp

Liên hệ QC

Quang_Hải

Thành viên gạo cội
Tham gia
21/2/09
Bài viết
6,038
Được thích
7,925
Nghề nghiệp
Làm đủ thứ
Chúng ta cùng khảo sát những ứng dụng cơ bản của VBScript RegExp
Thông thường khi muốn tách số ra khỏi 1 chuỗi lẫn lộn vừa số vừa chữ thì chúng ta hay dùng vòng lặp để xử lý, nhưng với VBR thì công việc này khá đơn giản với dạng code thế này

Ví dụ này ta chỉ chú ý đến .Pattern="\D"
Phương thức này sẽ tìm tất cả các ký tự không phải là số

Tiếp theo ta dùng phương thức .Replace để thay các ký tự được tìm thấy bằng chuỗi rỗng (xoá các ký tự đó) để còn lại kết quả là những con số

PHP:
Sub RegExp1()
Dim VBR As Object, kq
Set VBR = CreateObject("VBScript.RegExp")
With VBR
   For i = 1 To 5
      .Global = True
      .Pattern = "\D"
      Cells(i, 2) = .Replace(Cells(i, 1), "")
   Next
End With
End Sub

Cũng với code tương tự chúng ta có thể cộng các con số đựơc tìm thấy lại với nhau
Ở đây ta để ý đến phần .Pattern="\B"
Nếu chúng ta sử dụng .Pattern="" thì có nghĩa ta đang nói đến bắt đầu và kết thúc của 1 ký tự, khi ta muốn thêm dấu + giữa các con số tìm được thì ta có kết quả thế này: +1+2+3+4+5+

Nhưng với .Pattern = "\B" thì sẽ loại được dấu cộng không mong muốn ở đầu và cuối của dãy số tìm được. Sau đó chúng ta dùng hàm Evaluate để biến chuỗi này thành bài toán cộng

PHP:
Sub RegExp2()
Dim VBR As Object, kq
Set VBR = CreateObject("VBScript.RegExp")
With VBR
   For i = 1 To 5
      .Global = True
      .Pattern = "\D"
      kq = .Replace(Cells(i, 1), "")
      .Pattern = "\B"
      Cells(i, 2) = Evaluate(.Replace(kq, "+"))
   Next
End With
End Sub

Để tách lấy các ký tự trong 1 chuỗi lẫn lộn số và chữ ta sử dụng .Pattern="\d"
"\d" sẽ tìm tất cả con số trong chuỗi để xử lý
PHP:
Sub RegExp3()
Dim VBR As Object, kq
Set VBR = CreateObject("VBScript.RegExp")
With VBR
   For i = 1 To 5
      .Global = True
      .Pattern = "\d"
      Cells(i, 2) = .Replace(Cells(i, 1), "")
   Next
End With
End Sub
Nhưng không may trong chuỗi ký tự có những ký tự không phải là những mẫu tự, ta có thể dùng thế này "\W" kết hợp với "\d" để khử hết các ký tự đó. Nhưng không hiểu sao ký tự _ vẫn không được xử lý triệt để nên tôi phải kết hợp thêm dấu _ trong Pattern
Lưu ý là chúng ta không bàn đến tiếng việt có dấu nha

PHP:
Sub RegExp4()
Dim VBR As Object, kq
Set VBR = CreateObject("VBScript.RegExp")
With VBR
   For i = 1 To 5
      .Global = True
      .Pattern = "[\W\d,_]"
      Cells(i, 2) = .Replace(Cells(i, 1), "")
   Next
End With
End Sub
 
Lần chỉnh sửa cuối:
Để tách lấy các ký tự trong 1 chuỗi lẫn lộn số và chữ ta sử dụng .Pattern="\d"
"\d" sẽ tìm tất cả con số trong chuỗi để xử lý
PHP:
Sub RegExp3()
Dim VBR As Object, kq
Set VBR = CreateObject("VBScript.RegExp")
With VBR
   For i = 1 To 5
      .Global = True
      .Pattern = "\d"
      Cells(i, 2) = .Replace(Cells(i, 1), "")
   Next
End With
End Sub
Nhưng không may trong chuỗi ký tự có những ký tự không phải là những mẫu tự, ta có thể dùng thế này "\W" kết hợp với "\d" để khử hết các ký tự đó. Nhưng không hiểu sao ký tự _ vẫn không được xử lý triệt để nên tôi phải kết hợp thêm dấu _ trong Pattern
Lưu ý là chúng ta không bàn đến tiếng việt có dấu nha

PHP:
Sub RegExp4()
Dim VBR As Object, kq
Set VBR = CreateObject("VBScript.RegExp")
With VBR
   For i = 1 To 5
      .Global = True
      .Pattern = "[\W\d,_]"
      Cells(i, 2) = .Replace(Cells(i, 1), "")
   Next
End With
End Sub
Ý bạn là tách lấy ký tự AlphaB chăng? Vậy sao không .Pattern = "[^a-zA-Z]" cho khỏe?
 
Upvote 0
Chúng ta cùng khảo sát những ứng dụng cơ bản của VBScript RegExp
Để tách lấy các ký tự trong 1 chuỗi lẫn lộn số và chữ ta sử dụng .Pattern="\d"
"\d" sẽ tìm tất cả con số trong chuỗi để xử lý


PHP:
Sub RegExp3()
Dim VBR As Object, kq
Set VBR = CreateObject("VBScript.RegExp")
With VBR
   For i = 1 To 5
      .Global = True
      .Pattern = "\d"
      Cells(i, 2) = .Replace(Cells(i, 1), "")
   Next
End With
End Sub
Bình tĩnh, bình tĩnh. Cái pattern của bạn dùng để tách cái gì?
"Để tách lấy các ký tự"? Nhưng tách lấy "các ký tự" gì? Chữ số hay không chữ số thì phải nói rõ ra chứ "ký tự" thì ai mà hiểu được? Tôi hiểu là tách chữ số rồi thay bằng "", tức xóa.
Nhưng không may trong chuỗi ký tự có những ký tự không phải là những mẫu tự, ta có thể dùng thế này "\W" kết hợp với "\d" để khử hết các ký tự đó
"không phải là những mẫu tự" có nghĩa là không phải cái gì?
"Khử" là gì? Tôi hiểu là "khử" có nghĩa là tìm các "đoạn" khớp với pattern rồi thay chúng bằng "", tức xóa chúng. Ý của bạn là thế?
Nhưng không hiểu sao ký tự _ vẫn không được xử lý triệt để nên tôi phải kết hợp thêm dấu _ trong Pattern
Không khử triệt để nghĩa là gì? Nếu vd. bạn có chuỗi "12ab_345_678" và có code với pattern như sau - tức không có "_"
Mã:
Sub RegExp4()
Dim VBR As Object, kq
Set VBR = CreateObject("VBScript.RegExp")
With VBR
   For i = 1 To 5
      .Global = True
      .Pattern = "[\W\d]"
      Cells(i, 2) = .Replace(Cells(i, 1), "")
   Next
End With
End Sub
Thì bạn mong muốn nó trả về cái gì? Nếu tôi hiểu ý bạn từ pattern sau là "[\W\d,_]" thì bạn muốn tìm tất cả các chữ số và ký tự "_" rồi xóa chúng. Vậy thì bạn mong đợi cái gì với code ở trên? Mà trước tiên yêu cầu của bạn là gì? Là xóa hết các chữ số và ký tự "_"? Nếu thế thì bạn viết pattern sai chứ tại sao lại "Nhưng không hiểu sao ký tự _ vẫn không được xử lý triệt để"?
Code ở trên trả về "ab__" (2 dấu "_") thì đúng với pattern quá rồi còn gì?
Nếu bạn muốn xóa chữ số và cả ký tự "_" thì pattern là [\d_] hoặc "\d|_".
Mà bạn chú ý là "[\d_]" chứ không phải là "[\d,_]" đâu nhé. Các ký tự trong [...] nối tiếp nhau chứ không có các dấu phân cách chúng đâu nhé. Nếu bạn thêm dấu phẩy "," vào [...] thì vô tình bạn đã thêm vào pattern dấu ",", tức lúc đó là: xóa tất cả các chữ số, ký tự "_" và dấu phẩy, khác với yêu cầu thực của bạn.
Tóm lại bạn nên cho chuỗi cụ thể, miêu tả nó có dạng thế nào. Và nói yêu cầu của bạnn. Tiếp theo bạn có 2 lựa chọn:
1. Hỏi cách viết pattern thế nào
2. Cho 1 code cụ thể với pattern cụ thể và hỏi: Tại sao tôi mong nó trả về thế này thế này mà nó lại trả về thế kia thế kia? Tôi sai ở đâu.
Phải rõ ràng như thế mới thảo luận được. Vấn đề phải được nêu rõ, yêu cầu cụ thể thì mới thảo luận được.
 
Lần chỉnh sửa cuối:
Upvote 0
Theo hướng dẫn của anh NDU và anh Siwtom, mình tự đưa ra kết luận cho bản thân thế này

Nếu ta cần xử lý 1 chuỗi để lấy ra 1 chuỗi chỉ duy nhất là các chữ cái từ a-Z, thì Pattern này là hợp lý nhất

PHP:
    .Pattern = "[^a-zA-Z]"

Nhưng có điều là sau khi xử lý chuỗi không có cái dấu tiếng việt nào cả

Nhưng mình làm thế này thì có thể giữ lại dấu tiếng việt, nhưng phải chỉ định những gì cần xóa
Có điều mình không hiểu tại sao muốn chỉ định xóa cái dấu nhấy kép thì phải nhập 2 cái nháy thế này "" thì code mới chịu. Các anh xem và cho ý kiến giúp

PHP:
   .Pattern = "\d|_|'|-|""|,|"
 
Upvote 0
Có điều mình không hiểu tại sao muốn chỉ định xóa cái dấu nhấy kép thì phải nhập 2 cái nháy thế này "" thì code mới chịu. Các anh xem và cho ý kiến giúp

PHP:
   .Pattern = "\d|_|'|-|""|,|"

Dùng 1 ví dụ khác nhé!
Ta có công thức =IF(A1="", "", "A1)
Giờ nếu như ta viết code VBA để chèn công thức trên vào cell B1 thì bạn sẽ viết thế nào? Từ đó suy ra cái bạn thắc mắc
 
Upvote 0
Giờ chúng ta có 1 chuỗi thế này

12345sadsa12345asdasd

Và chúng ta muốn cộng 2 dãy số bên trong lại với nhau để có kết quả là 24690
Mình dùng code thế này thì cộng lại được, nhưng liệu có cách nào ngắn gọn hơn không?
Có cách nào kết hợp 2 lần .Pattern thành 1 hay không?
PHP:
Sub Congso_RegExp()
Dim i, kq
  With CreateObject("VBScript.RegExp")
    For i = 1 To 5
      .Global = True
      .Pattern = "\D"
      kq = Application.Trim(.Replace(Cells(i, 1), " "))
      .Pattern = " "
      Cells(i, 2) = Evaluate(.Replace(kq, "+"))
    Next
  End With
End Sub
 
Upvote 0
Giờ chúng ta có 1 chuỗi thế này

12345sadsa12345asdasd

Và chúng ta muốn cộng 2 dãy số bên trong lại với nhau để có kết quả là 24690
Mình dùng code thế này thì cộng lại được, nhưng liệu có cách nào ngắn gọn hơn không?
Có cách nào kết hợp 2 lần .Pattern thành 1 hay không?
PHP:
Sub Congso_RegExp()
Dim i, kq
  With CreateObject("VBScript.RegExp")
    For i = 1 To 5
      .Global = True
      .Pattern = "\D"
      kq = Application.Trim(.Replace(Cells(i, 1), " "))
      .Pattern = " "
      Cells(i, 2) = Evaluate(.Replace(kq, "+"))
    Next
  End With
End Sub
Nghĩ được cái này:
PHP:
Sub Congso_RegExp()
  Dim i, kq
  With CreateObject("VBScript.RegExp")
    For i = 1 To 5
      .Global = True
      .Pattern = "\D"
      kq = .Replace(Cells(i, 1), "+0")
      Cells(i, 2) = Evaluate(kq)
    Next
  End With
End Sub
Góp ý: Một là cho file lên, Hai là viết thành Function cho dễ test bạn à
 
Upvote 0
Giờ chúng ta có 1 chuỗi thế này

12345sadsa12345asdasd

Và chúng ta muốn cộng 2 dãy số bên trong lại với nhau để có kết quả là 24690
Mình dùng code thế này thì cộng lại được, nhưng liệu có cách nào ngắn gọn hơn không?
Có cách nào kết hợp 2 lần .Pattern thành 1 hay không?
PHP:
Sub Congso_RegExp()
Dim i, kq
  With CreateObject("VBScript.RegExp")
    For i = 1 To 5
      .Global = True
      .Pattern = "\D"
      kq = Application.Trim(.Replace(Cells(i, 1), " "))
      .Pattern = " "
      Cells(i, 2) = Evaluate(.Replace(kq, "+"))
    Next
  End With
End Sub
Ngắn gọn hơn hay không thì mình ....cóc có biết, nhưng với đề bài này & sử dụng RegExp thì mình làm thế này:
Mã:
Public Function Tong(Cll As Range) As Long
    Dim Re As Object, A, KetQua, Tim, ReTim
    Set Re = CreateObject("vbscript.regexp")
    With Re
        .Global = True
        .Pattern = "\d+"
       Set ReTim = Re.Execute(Cll)
    End With
            For Each Tim In ReTim
                KetQua = KetQua + Val(Tim.Value)
            Next Tim
    Tong = KetQua
End Function
Híc
 

File đính kèm

  • Book1.xls
    26.5 KB · Đọc: 141
Upvote 0
Anh Cò và anh NDU giải thích ý nghĩa của mấy cái này dùm em

"+0"
"\d+"
.Execute(Cll)
 
Upvote 0
Anh Cò và anh NDU giải thích ý nghĩa của mấy cái này dùm em


"\d+"
.Execute(Cll)
Mắc cười quá, anh & chú em đều là dân học.......mò sao lại hỏi câu đó:
1- "\d+": sao không bỏ dấu cộng đi coi code nó làm cái quái gì & kết quả ra răng thì hiểu ngay thôi mà, còn nếu hổng hiểu thì....từ từ sẽ hiểu
2- Execute: câu này mình chơi ngôn ngữ quốc tế với nhau nhé:
Execute là một trong 3 Methods của RegExp, 2 thằng kia là Replace & Test. Đại khái như thế này: Execute(Cll) thực hiện lệnh so sánh xem chuỗi Cll có chứa em nào khớp với thằng Pattern hay không, nếu có kết quả trả về là một mảng, muốn lấy em nào thì duyệt qua mảng í để lấy
Híc
 
Upvote 0
Execute(Cll) thực hiện lệnh so sánh xem chuỗi Cll có chứa em nào khớp với thằng Pattern hay không, nếu có kết quả trả về là một mảng, muốn lấy em nào thì duyệt qua mảng í để lấy
Híc
Hổng phải MẢNG anh à! Nó là Collection ----> Là 1 mớ hổn độn chứ không có chiều như mảng
 
Upvote 0
"\d+" : có nghĩa là ký tự số trong "chuỗi mẫu (pattern)" có thể xuất hiện 1 hoặc nhiều lần nhưng ít nhất phải xuất hiện 1 lần.
 
Upvote 0
Tiếp tục chủ đề này với hàm tách tên
Trước đây mình thường dùng hàm này để tách tên

PHP:
Function tachten(cell As Range)
   tachten = Right(cell, Len(cell) - InStrRev(cell, " "))
End Function

Nhưng thấy cách dùng này của RegExp cũng hay nên up lên để mọi người tham khảo

PHP:
Function tachten(cell As Range)
   With CreateObject("vbscript.regexp")
      .Global = True
      .Pattern = ".* "
      tachten = .Replace(cell, "")
   End With
End Function

Ứng dụng cách này mình cũng có thể loại bỏ 1 chuỗi ký tự trước 1 ký tự nào đó
Ví dụ ta có chuỗi "Nguyen, Van Minh" <ami8688@gmail.com>,
Dùng hàm này có thể loại bỏ "Nguyen, Van Minh" ra khỏi chuỗi để lấy ra địa chỉ mail

PHP:
Function tach(cell As Range)
   With CreateObject("vbscript.regexp")
      .Global = True
      .Pattern = ".*"" "
      tach = .Replace(cell, "")
   End With
End Function
 
Lần chỉnh sửa cuối:
Upvote 0
Ví dụ nha, trong 1 cell có 2 đk cần thay thế, chuỗi là: Hoang:Trong=Nghia

Tôi muốn kết quả là Hoang Trong Nghia thì phải dùng Pattern như thế nào?

Chẳng lẽ phải dùng đến 2 lần Pattern?

R = "Hoang:Trong=Nghia"
With CreateObject("vbscript.regexp")
.Global = True
.Pattern = ":"
R= .Replace(R), " ")
.Pattern = "="
R= .Replace(R, " ")
End With
 
Lần chỉnh sửa cuối:
Upvote 1
Web KT
Back
Top Bottom