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,050
Được thích
7,947
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:

File đính kèm

  • Doc1.rar
    184.7 KB · Đọc: 49
Upvote 0
Upvote 0
Tôi đã đọc chủ để này không biết bao nhiêu lần và mỗi khi đọc đến bài cuối tôi lại tự nhủ "Coi như chưa thấy nó" - đó là bí quyết của tôi đối với những cám dỗ mà mình lực bất tòng tâm.

Hôm nay xem bài này http://www.giaiphapexcel.com/forum/...ấu-xuống-dòng-(Alt-Enter)&p=514244#post514244
Tôi lại chui vào đây với hi vọng sẽ hiểu thêm đoạn code này (những chữ màu đỏ)

Mã:
            With CreateObject("VbScript.Regexp")
                .Global = True
[COLOR=#ff0000]                .MultiLine = True[/COLOR]
                .Pattern =[COLOR=#ff0000] "^.*$"[/COLOR]
                For Each Match In .Execute(sh.Cells(rw, col))
                    i = i + 1
                    Arr(i, col) = Replace(Match, ",", ".")
                Next
            End With
nhưng lại "tẩu hỏa nhập ma" bởi

.Pattern ="\b(\w+)\b([\w\W]*)\b\1\b" .
.Pattern = "\b(\w+)(?:\s+\1)+\b"
.Pattern = ........

Vậy các bạn có thể chú giải giúp tôi ý nghĩa đơn của từng mẫu Pattern được không (ý muốn hỏi "cái gì là cái gì ấy mà" ? để tôi biết nó là cái giống gì mà khoai thế). Thanks !

Về ký tự "^" thì nó không đại diện cho bất cứ ký tự nào trong chuỗi cả. Ký tự đó chỉ có nghĩa là "vị trí ở đầu chuỗi". Vd. ta có Pattern = "^abc" thì có nghĩa là tìm tất cả các đoạn khớp với mẫu "^abc", tức các đoạn mà bắt đầu bằng vị trí đầu chuỗi và tiếp theo là 3 ký tự "abc". Nói nôm na là tìm các đoạn "abc" mà ở đầu chuỗi (trước "a" là "vị trí đầu chuỗi"). Tất nhiên "vị trí đầu chuỗi" chỉ có 1 nên nếu chuỗi cho trước có đoạn khớp với mẫu thì cũng chỉ có 1 đoạn khớp.
Tượng tự ký tự "$" trong Pattern xác định "vị trí cuối chuỗi" chứ không đại diện cho bất cứ ký tự nào trong chuỗi.Ví dụ có chuỗi s = "abcde xyz" và Pattern = "^abc" => tìm thấy 1 đoạn khớp "abc". Nếu Pattern = "yz$" => tìm thấy 1 đoạn khớp "yz".
Chú ý:
1. Ký tự "^" trong cấu trúc [^...] có ý nghĩa khác.
[abcxyz] có nghĩa là 1 ký tự trong tập {a, b, c, x, y, z}
[^abcxyz] có nghĩa là 1 ký tự KHÔNG thuộc tập {a, b, c, x, y, z}
2. Mặc định thì MultiLine = FALSE. Nếu MultiLine = TRUE thì "^" cũng có nghĩa là "vị trí đầu dòng" và "$" có nghĩa là "vị trí cuối dòng"

Trở về Pattern của tôi thì cần hiểu thêm ký tự "." (dấu chấm). Ký tự "." trong pattern có nghĩa là một ký tự bất kỳ khác ký tự \n (xuống dòng, dòng mới). Ký tự sao "*" có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc > 0 lần
Vậy
Mã:
                .MultiLine = True
                .Pattern = "^.*$"

Có nghĩa là: "tìm tất cả cả các đoạn mà mỗi đoạn là chuỗi (có độ lớn >= 0) các ký tự bất kỳ khác ký tự xuống dòng, bắt đầu từ vị trí đầu dòng và kết thúc bằng vị trí cuối dòng". Dịch ra ngôn ngữ dễ hiểu thì là: Tìm tất cả các dòng (kể cả dòng trống, tức có độ lớn = 0 - ký tự "." xuất hiện 0 lần) có trong chuỗi.
---------------
Bảng các ký tự

Ký tự|Ý nghĩa
Ký tự|Mối ký tự, trừ các ký tự đặc biệt [\^$.|?*+(), có nghĩa là chính mình, vd. g là g Ký tự { và } là chính mình nếu chúng không phải là một phần của biểu thức, vd. Như trong \d{3}
.|Dấu chấm đại diện cho 1 ký tự bất kỳ trừ ký tự \n
\|Các ký tự [\^$.|?*+(){} sau ký tự \ có nghĩa là chính mình, vd. \. có nghĩa là dấu chấm chứ không phải ký tự bất kỳ. \\ có nghĩa là \, còn \( có nghĩa là (
\Q...\E|chuỗi ký tự giữa \Q và \E (kể cả các ký tự đặc biệt) có nghĩa là chính mình? Vd. \Q+-*/\E khớp với +-*/
^|Đầu chuỗi
$|Cuối chuỗi
*|Ký tự sao * có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc > 0 lần, vd. “zo*” có nghĩa là “z” hoặc “zo...o”
+|Ký tự + có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện ít nhất 1 lần. vd. “zo+” có thể là “zo” hoặc “zo...o” nhưng không là “z”
?|Dấu hỏi ? có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc 1 lần
{n,}|Có nghĩa là biểu thức được lặp lại ít nhất là n lần. vd.: "o{2,}" không có nghĩa "o" trong "Bob" nhưng có nghĩa là tất cả các ký tự "o" trong "foooood." o{1,} tương đương với "o+" còn "o{0,}" tương đương với "o*".
{n,m}
n >= 0,
m >= n|Có nghĩa là biểu thức phải được lặp lại ít nhất n lần nhưng không quá m lần. Vd. "o{1,3}" có nghĩa là "ooo" trong "fooooood" còn "o{0,1}" tương đương với "o?".
*?|Ký tự sao * có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc > 0 lần, vd. “zo*” có nghĩa là “z” hoặc “zo...o”
"+?"|Ký tự + có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện ít nhất 1 lần. vd. “zo+” có thể là “zo” hoặc “zo...o” nhưng không là “z”
??|Dấu hỏi ? có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc 1 lần
{n,}?|Có nghĩa là biểu thức được lặp lại ít nhất là n lần. vd.: "o{2,}" không có nghĩa "o" trong "Bob" nhưng có nghĩa là tất cả các ký tự "o" trong "foooood." o{1,} tương đương với "o+" còn "o{0,}" tương đương với "o*".
{n,m}?
n >= 0,
m >= n|Có nghĩa là biểu thức phải được lặp lại ít nhất n lần nhưng không quá m lần. Vd. "o{1,3}" có nghĩa là "ooo" trong "fooooood" còn "o{0,1}" tương đương với "o?".
x|y|Dấu gạch đứng | là toán tử OR, vd. Nếu ta viết a|b|c thì có nghĩa là trong biểu thức xuất hiện a hoặc b hoặc c. Có thể dùng ngoặc để nhóm, vd. abc(def|xyz) khớp với abcdef hoặc abcxyz
{n}|Số n xác định ký tự hoặc biểu thức trước nó được lặp lại bao nhiêu lần Vd. “o{2}” có nghĩa là “oo”
[xyz]
[a-z]|Tập ký tự trong ngoặc vuông [] có nghĩa là 1 ký tự bất kỳ trong tập đó, vd. [abc] có nghĩa là a, b hoặc c cũng có thể dùng khoảng: [a-c]. Nếu muốn dùng các ký tự ^-]\ trong tập thì phải thêm vào đằng trước ký tự "\", vd. [\^\]] có nghĩa là "^" hoặc "]"
[^xyz]
[^m-z]|Ký tự ^ ở đầu tập có nghĩa là mọi ký tự trừ ký tự trong tập. Cũng có thể dùng khoảng.
\b|xác định vị trí nằm giữa từ (tức chuỗi các ký tự thuộc [a-zA-Z0-9_]) và ký tự [^A-Za-z0-9_]. Cũng có nghĩa là vị trí ^ hoặc $ nếu ký tự đầu tiên hoặc cuối cùng trong chuỗi thuộc [A-Za-z0-9_] Vd. "er\b" khớp với "er" trong "never" nhưng không khớp với "er" trong "verb". "\b" ở trong […] có nghĩa là ký tự backspace - "\x08". "[\b]" khớp với "\x08"
\B|xác định vị trí giữa 2 ký tự liên tiếp cùng thuộc [A-Za-z0-9_] hoặc cùng thuộc [^A-Za-z0-9_], vd. "ea*r\B" khớp với "ear" trong "never early".
\d|Có nghĩa là chữ số, tương đương với [0-9]. Được phép dùng trong […]
\D|Có nghĩa là không là chữ số, tương đương với [^0-9]
\a và \e|khớp với ký tự bell (\x07) và escape (\x1B). Được phép dùng trong […]
\f|ký tự điều khiển nhả trang - form feed. Được phép dùng trong […]
\n|Có nghĩa là ký tự dòng mới. Được phép dùng trong […]
\r|Có nghĩa là ký tự về đầu dòng. Được phép dùng trong […]
\s|Có nghĩa là tất cả các dấu cách trắng, tức dấu cách, TAB, form-feed, .... Tương đương với "[ \f\n\r\t\v]". Được phép dùng trong […]
\S|Có nghĩa là tất cả các ký tự trừ các dấu cách trắng. Tương đương với "[^ \f\n\r\t\v]"
\t|Có nghĩa là ký tự TAB. Được phép dùng trong […]
\v|ký tự điều khiển vertical tab. Được phép dùng trong […]
\w|Tương đương với "[A-Za-z0-9_]". Được phép dùng trong […]
\W|Tương đương với "[^A-Za-z0-9_]".
()\num|Matches num, where num is a positive integer. A reference back to remembered matches. For example, "(.)\1" matches two consecutive identical characters.
\n|Matches n, where n is an octal escape value. Octal escape values must be 1, 2, or 3 digits long. For example, "\11" and "\011" both match a tab character. "\0011" is the equivalent of "\001" & "1" Octal escape values must not exceed 256. If they do, only the first two digits comprise the expression. Allows ASCII codes to be used in regular expressions.
\xFF với FF là 2 ký tự hệ 16|khớp với ký tự có điểm mã là FF. vd. "\x41" khớp với ký tự "A", "\x041" khớp với "\x04" & "1". Được phép dùng trong […]

Thiết lập mặc định là "tham lam" (Greedy), tức tìm những đoạn dài nhất có thể mà khớp với mẫu. Nếu ta muốn tìm những đoạn ngắn nhất có thể mà khớp với mẫu thì thay vì *, +, ?, {n,}, {n,m} ta dùng phiên bản "lười biếng" (Lazy) của chúng: *?, +?, ??, {n,}?, {n,m}?
 

File đính kèm

  • bang ky tu.xlsx
    10.5 KB · Đọc: 95
Lần chỉnh sửa cuối:
Upvote 0

File đính kèm

  • Script.rar
    2.7 MB · Đọc: 207
Lần chỉnh sửa cuối:
Upvote 0
Để tách tên mình dùng Pattern này
PHP:
Function ten(cell As Range)
   With CreateObject("vbscript.regexp")
      .Global = True
      .Pattern = ".*\s"
      ten = .Replace(Trim(cell), "")
   End With
End Function
Để tách lấy họ mình dùng Pattern này
PHP:
Function ho(cell As Range)
   With CreateObject("vbscript.regexp")
      .Global = True
      .Pattern = "\s.*"
      ho = .Replace(Trim(cell), "")
   End With
End Function
Xin hỏi các anh chị ngoài cách dưới đây có cách nào dùng 1 Pattern để lấy được các ký tự bên trong của dấu cách đầu và dấu cách cuối để tách phần tên lót ra hay không?
PHP:
Function tenlot(cell As Range)
Dim ho As String, ten As String
   With CreateObject("vbscript.regexp")
      .Global = True
      .Pattern = ".*\s"
      ten = .Replace(Trim(cell), "")
      .Pattern = "\s.*"
      ho = .Replace(Trim(cell), "")
      tenlot = Application.Trim(Replace(Replace(cell, ho, ""), ten, ""))
   End With
End Function
mới thấy trên diễn đàn cắt lấy tên bằng tìm kiếm và thay thế "* " thấy áp dụng được các trường hợp mình test "mình có thể sử lý các trắng thừa trước" sau đó áp dụng vào cái này thấy rất ok, mong các thành viên xem xét xem có trường hợp nào bị lỗi không

hàm cắt tên
Mã:
Sub VBSCRIPT()
Dim luat As Object
    Set luat = CreateObject("vbscript.regexp")
    luat.Global = True
    luat.Pattern = ".* "
    For i = 1 To 20
          Cells(i, 2) = luat.Replace(Cells(i, 1), "")
    Next
End Sub
 
Lần chỉnh sửa cuối:
Upvote 0
mới thấy trên diễn đàn cắt lấy tên bằng tìm kiếm và thay thế "* " thấy áp dụng được các trường hợp mình test "mình có thể sử lý các trắng thừa trước" sau đó áp dụng vào cái này thấy rất ok, mong các thành viên xem xét xem có trường hợp nào bị lỗi không

hàm cắt tên
Mã:
Sub VBSCRIPT()
Dim luat As Object
    Set luat = CreateObject("vbscript.regexp")
    luat.Global = True
    For i = 1 To 20
         luat.Pattern = ".* "
         Cells(i, 2) = luat.Replace(Cells(i, 1), "")
    Next
End Sub

Bạn không cho biết mục đich của hàm. Lấy gì mà xét xem nó đúng hay sai? Cắt tên nghĩa là gì? Cắt tên bỏ đi giữ lại họ, hay là cắt tên giữ lại và bọ họ đi?

Đúng hay sai chưa biết. Nhưng code dở ở hai điểm:

1. Cái Pattern không hề thay đổi. Để nó trong vòng lặp để chép đi chép lại 20 lần à?

2. Khi cần tách lấy một cụm ký tự thì dùng phương thức Match rồi lấy ra. Dùng phương thức Replace để xoá phần thừa là cách làm ngược.
 
Upvote 0
mới thấy trên diễn đàn cắt lấy tên bằng tìm kiếm và thay thế "* " thấy áp dụng được các trường hợp mình test "mình có thể sử lý các trắng thừa trước" sau đó áp dụng vào cái này thấy rất ok, mong các thành viên xem xét xem có trường hợp nào bị lỗi không

hàm cắt tên
Mã:
Sub VBSCRIPT()
Dim luat As Object
    Set luat = CreateObject("vbscript.regexp")
    luat.Global = True
    luat.Pattern = ".* "
    For i = 1 To 20
          Cells(i, 2) = luat.Replace(Cells(i, 1), "")
    Next
End Sub
Muốn tách lấy phần tên thì hãy tham khảo cách này của mình.
Cũng hơi nhức đầu tí nhưng nhìn thấy chuyên nghiệp lắm.
PHP:
Function TachTen(Str As String) As String
   With CreateObject("vbscript.regexp")
       .Global = True
       .Pattern = "(\S+$)"
       TachTen = Trim(.Execute(Trim(Str))(0).Submatches(0))
   End With
End Function
 
Upvote 0
Muốn tách lấy phần tên thì hãy tham khảo cách này của mình.
Cũng hơi nhức đầu tí nhưng nhìn thấy chuyên nghiệp lắm.
PHP:
Function TachTen(Str As String) As String
   With CreateObject("vbscript.regexp")
       .Global = True
       .Pattern = "(\S+$)"
       TachTen = Trim(.Execute(Trim(Str))(0).Submatches(0))
   End With
End Function
Lâu lắm mới thấy anh!
A bổ sung thêm code tách họ, tách đệm cho mng nghiên cứu đi anh.
 
Upvote 0
Lâu lắm mới thấy anh!
A bổ sung thêm code tách họ, tách đệm cho mng nghiên cứu đi anh.
Mấy đồ quỷ này giờ xưa lắm rồi nên ít thấy ai quan tâm. Hứa với nhau là đừng kêu giải thích mấy cái mì tôm cua của pattern nhé.

PHP:
Function TachTen(Str$, Optional Op As Long = 3)
With CreateObject("vbscript.regexp")
    .Global = True
    .Pattern = "(\S+)( .+ | )(\S+$)"
    TachTen = Trim(.Execute(Trim(Str))(0).Submatches(Op - 1))
End With
End Function
 
Upvote 0
Thuật toán của anh Hải có một vài chỗ chưa đúng. Do sử dụng phương thức Replace nên nếu rơi vào một trong các trường hợp sau đây kết quả sẽ không đúng:
1. Họ là chuỗi con của Tên ( Thị n)
2. Họ là chuỗi con của tên lót (Hồ Thị Hồng Hà)
3. Tên là chuỗi con của tên lót (Nguyễn Thị Thanh Thanh)

Tôi cũng viết thử một hàm 3 trong 1. Có thể tách họ, tên lót, tên.
[gpecode=vb]Function TachTen(Str As String, Optional Op As Long = 3)
With CreateObject("vbscript.regexp")
.Global = True
.Pattern = "(\S+)( .+ | )(\S+$)"
TachTen = Trim(.Execute(Trim(Str))(0).SubMatches(Op - 1))
End With
End Function[/gpecode]
Em cũng đang dùng hàm trên để xếp ABC cho danh sách học sinh:
Code VBA em đang dùng:
Sub XeptenABC()
Application.ScreenUpdating = False
Dim n As Long
n = Sheet2.[c65000].End(3).Row
Range("do7:do" & n).FormulaR1C1 = "=MahoaUNI(TachTen(RC3,3))"
Range("dp7:dp" & n).FormulaR1C1 = "=MahoaUNI(TachTen(RC3,2))"
Range("dq7:dq" & n).FormulaR1C1 = "=MahoaUNI(tachten(RC3,1))"
Range("B7:dq" & n).Sort Key1:=[do7], Order1:=1, Key2:=[dp7], Order2:=1, Key3:=[dq7], Order3:=1, Header:=xlNo
Range("do7:dq" & n).Clear

Application.ScreenUpdating = True
MsgBox "Da xep xong!"
End Sub

Function TachTen(str As String, Optional Op As Long = 3)
With CreateObject("vbscript.regexp")
.Global = True
.Pattern = "(\S+)( .+ | )(\S+$)"
TachTen = Trim(.Execute(Trim(str))(0).SubMatches(Op - 1))
End With
End Function

Public Function MahoaUNI(S) As String
Dim x, Sb, k, mu, skdau, sdau, Bdau, Bkdau As String
Dim i, m, n, dau, idau, ikdau As Integer

If IsNull(S) Then
Exit Function
ElseIf IsNumeric(S) Then
Sb = S
Else
S = Trim(S)
S = LCase(S) & ChrW(32)

skdau = ChrW(259) & ChrW(234) & ChrW(244) & ChrW(432) & ChrW(273) & ChrW(226) & ChrW(417)
Bkdau = "aeoudao"

sdau = ChrW(225) & ChrW(224) & ChrW(7843) & ChrW(227) & ChrW(7841) _
& ChrW(233) & ChrW(232) & ChrW(7867) & ChrW(7869) & ChrW(7865) _
& ChrW(237) & ChrW(236) & ChrW(7881) & ChrW(297) & ChrW(7883) _
& ChrW(243) & ChrW(242) & ChrW(7887) & ChrW(245) & ChrW(7885) _
& ChrW(250) & ChrW(249) & ChrW(7911) & ChrW(361) & ChrW(7909) _
& ChrW(253) & ChrW(7923) & ChrW(7927) & ChrW(7929) & ChrW(7925) _
& ChrW(7855) & ChrW(7857) & ChrW(7859) & ChrW(7861) & ChrW(7863) _
& ChrW(7889) & ChrW(7891) & ChrW(7893) & ChrW(7895) & ChrW(7897) _
& ChrW(7871) & ChrW(7873) & ChrW(7875) & ChrW(7877) & ChrW(7879) _
& ChrW(7913) & ChrW(7915) & ChrW(7917) & ChrW(7919) & ChrW(7921) _
& ChrW(7845) & ChrW(7847) & ChrW(7849) & ChrW(7851) & ChrW(7853) _
& ChrW(7899) & ChrW(7901) & ChrW(7903) & ChrW(7905) & ChrW(7907)
Bdau = "aaaaaeeeeeiiiiiooooouuuuuyyyyyaaaaaoooooeeeeeuuuuuaaaaaooooo"

For m = 1 To Len(S)
k = Mid(S, m, 1)
idau = InStr(1, sdau, k, 0)
ikdau = InStr(1, skdau, k, 0)
If idau > 0 Then
k = Mid(Bdau, idau, 1)
dau = idau Mod 5

If dau = 0 Then
dau = 5
End If


If idau > 0 And idau < 31 Then
mu = ""
ElseIf idau > 30 And idau < 51 Then
mu = "z"
Else
mu = "zw"
End If

k = k & mu

ElseIf ikdau > 0 Then
k = Mid(Bkdau, ikdau, 1)
If ikdau < 6 Then
k = k & "z"
Else
k = k & "zw"
End If
ElseIf k = ChrW(32) Then
k = dau & ChrW(32)
dau = ""
End If

x = x & k
Next
Sb = Sb & x
End If
MahoaUNI = Sb
End Function

Tuy nhiên DSHS xếp chưa được như ý muốn
VD 2 học sinh sau khi xếp thì có thứ tự như sau:
1. Nguyễn Quỳnh Nhi
2. Nguyễn Thị Anh Nhi

Nhưng theo đúng DSHS của GVCN lớp lại xếp là:
1. Nguyễn Thị Anh Nhi
2. Nguyễn Quỳnh Nhi

(Chắc là lấy từng tên đệm gần tên chính trước, sau đó dịch dần về phía Họ, vì tên đệm của học sinh có thể 1 từ, 2 từ, ... )
Bây giờ em muốn xếp DSHS theo GVCN lớp xếp thì em cần sửa gì không?
Mong mọi người trên GPE giúp em với, xin cảm ơn mọi người....
 
Upvote 0
Đã lập 40 cái chủ đề, hơn 200 bài viết mà không biết trình bày sao cho hợp lý.

Nội quy diễn đàn nên bổ sung điều khoản trình bày bài viết... như bài trên khác gì mớ rau.

Nhũng não, não nề...

1536682226930.png
 
Upvote 0
Upvote 0
Thì cứ.. kệ người ta đi bạn!
Tất nhiên em kệ người ta rồi. Chỉ là suy nghĩ thoảng qua của em, góp ý kiến ý cò với diễn đàn.
Mà em ý kiến vậy chỉ tổ thêm người ghét mình.
Diễn đàn ít bài kiểu như thế hay nhiều bài như thế cũng không ảnh hưởng gì tới em, nhưng chắc chắn ảnh hưởng tới diễn đàn.
 
Upvote 0
Về ký tự "^" thì nó không đại diện cho bất cứ ký tự nào trong chuỗi cả. Ký tự đó chỉ có nghĩa là "vị trí ở đầu chuỗi". Vd. ta có Pattern = "^abc" thì có nghĩa là tìm tất cả các đoạn khớp với mẫu "^abc", tức các đoạn mà bắt đầu bằng vị trí đầu chuỗi và tiếp theo là 3 ký tự "abc". Nói nôm na là tìm các đoạn "abc" mà ở đầu chuỗi (trước "a" là "vị trí đầu chuỗi"). Tất nhiên "vị trí đầu chuỗi" chỉ có 1 nên nếu chuỗi cho trước có đoạn khớp với mẫu thì cũng chỉ có 1 đoạn khớp.
Tượng tự ký tự "$" trong Pattern xác định "vị trí cuối chuỗi" chứ không đại diện cho bất cứ ký tự nào trong chuỗi.Ví dụ có chuỗi s = "abcde xyz" và Pattern = "^abc" => tìm thấy 1 đoạn khớp "abc". Nếu Pattern = "yz$" => tìm thấy 1 đoạn khớp "yz".
Chú ý:
1. Ký tự "^" trong cấu trúc [^...] có ý nghĩa khác.
[abcxyz] có nghĩa là 1 ký tự trong tập {a, b, c, x, y, z}
[^abcxyz] có nghĩa là 1 ký tự KHÔNG thuộc tập {a, b, c, x, y, z}
2. Mặc định thì MultiLine = FALSE. Nếu MultiLine = TRUE thì "^" cũng có nghĩa là "vị trí đầu dòng" và "$" có nghĩa là "vị trí cuối dòng"

Trở về Pattern của tôi thì cần hiểu thêm ký tự "." (dấu chấm). Ký tự "." trong pattern có nghĩa là một ký tự bất kỳ khác ký tự \n (xuống dòng, dòng mới). Ký tự sao "*" có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc > 0 lần
Vậy
Mã:
                .MultiLine = True
                .Pattern = "^.*$"

Có nghĩa là: "tìm tất cả cả các đoạn mà mỗi đoạn là chuỗi (có độ lớn >= 0) các ký tự bất kỳ khác ký tự xuống dòng, bắt đầu từ vị trí đầu dòng và kết thúc bằng vị trí cuối dòng". Dịch ra ngôn ngữ dễ hiểu thì là: Tìm tất cả các dòng (kể cả dòng trống, tức có độ lớn = 0 - ký tự "." xuất hiện 0 lần) có trong chuỗi.
---------------
Bảng các ký tự

Ký tự|Ý nghĩa
Ký tự|Mối ký tự, trừ các ký tự đặc biệt [\^$.|?*+(), có nghĩa là chính mình, vd. g là g Ký tự { và } là chính mình nếu chúng không phải là một phần của biểu thức, vd. Như trong \d{3}
.|Dấu chấm đại diện cho 1 ký tự bất kỳ trừ ký tự \n
\|Các ký tự [\^$.|?*+(){} sau ký tự \ có nghĩa là chính mình, vd. \. có nghĩa là dấu chấm chứ không phải ký tự bất kỳ. \\ có nghĩa là \, còn \( có nghĩa là (
\Q...\E|chuỗi ký tự giữa \Q và \E (kể cả các ký tự đặc biệt) có nghĩa là chính mình? Vd. \Q+-*/\E khớp với +-*/
^|Đầu chuỗi
$|Cuối chuỗi
*|Ký tự sao * có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc > 0 lần, vd. “zo*” có nghĩa là “z” hoặc “zo...o”
+|Ký tự + có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện ít nhất 1 lần. vd. “zo+” có thể là “zo” hoặc “zo...o” nhưng không là “z”
?|Dấu hỏi ? có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc 1 lần
{n,}|Có nghĩa là biểu thức được lặp lại ít nhất là n lần. vd.: "o{2,}" không có nghĩa "o" trong "Bob" nhưng có nghĩa là tất cả các ký tự "o" trong "foooood." o{1,} tương đương với "o+" còn "o{0,}" tương đương với "o*".
{n,m}
n >= 0,
m >= n|Có nghĩa là biểu thức phải được lặp lại ít nhất n lần nhưng không quá m lần. Vd. "o{1,3}" có nghĩa là "ooo" trong "fooooood" còn "o{0,1}" tương đương với "o?".
*?|Ký tự sao * có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc > 0 lần, vd. “zo*” có nghĩa là “z” hoặc “zo...o”
"+?"|Ký tự + có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện ít nhất 1 lần. vd. “zo+” có thể là “zo” hoặc “zo...o” nhưng không là “z”
??|Dấu hỏi ? có nghĩa là ký tự hoặc biểu thức trước nó xuất hiện 0 hoặc 1 lần
{n,}?|Có nghĩa là biểu thức được lặp lại ít nhất là n lần. vd.: "o{2,}" không có nghĩa "o" trong "Bob" nhưng có nghĩa là tất cả các ký tự "o" trong "foooood." o{1,} tương đương với "o+" còn "o{0,}" tương đương với "o*".
{n,m}?
n >= 0,
m >= n|Có nghĩa là biểu thức phải được lặp lại ít nhất n lần nhưng không quá m lần. Vd. "o{1,3}" có nghĩa là "ooo" trong "fooooood" còn "o{0,1}" tương đương với "o?".
x|y|Dấu gạch đứng | là toán tử OR, vd. Nếu ta viết a|b|c thì có nghĩa là trong biểu thức xuất hiện a hoặc b hoặc c. Có thể dùng ngoặc để nhóm, vd. abc(def|xyz) khớp với abcdef hoặc abcxyz
{n}|Số n xác định ký tự hoặc biểu thức trước nó được lặp lại bao nhiêu lần Vd. “o{2}” có nghĩa là “oo”
[xyz]
[a-z]|Tập ký tự trong ngoặc vuông [] có nghĩa là 1 ký tự bất kỳ trong tập đó, vd. [abc] có nghĩa là a, b hoặc c cũng có thể dùng khoảng: [a-c]. Nếu muốn dùng các ký tự ^-]\ trong tập thì phải thêm vào đằng trước ký tự "\", vd. [\^\]] có nghĩa là "^" hoặc "]"
[^xyz]
[^m-z]|Ký tự ^ ở đầu tập có nghĩa là mọi ký tự trừ ký tự trong tập. Cũng có thể dùng khoảng.
\b|xác định vị trí nằm giữa từ (tức chuỗi các ký tự thuộc [a-zA-Z0-9_]) và ký tự [^A-Za-z0-9_]. Cũng có nghĩa là vị trí ^ hoặc $ nếu ký tự đầu tiên hoặc cuối cùng trong chuỗi thuộc [A-Za-z0-9_] Vd. "er\b" khớp với "er" trong "never" nhưng không khớp với "er" trong "verb". "\b" ở trong […] có nghĩa là ký tự backspace - "\x08". "[\b]" khớp với "\x08"
\B|xác định vị trí giữa 2 ký tự liên tiếp cùng thuộc [A-Za-z0-9_] hoặc cùng thuộc [^A-Za-z0-9_], vd. "ea*r\B" khớp với "ear" trong "never early".
\d|Có nghĩa là chữ số, tương đương với [0-9]. Được phép dùng trong […]
\D|Có nghĩa là không là chữ số, tương đương với [^0-9]
\a và \e|khớp với ký tự bell (\x07) và escape (\x1B). Được phép dùng trong […]
\f|ký tự điều khiển nhả trang - form feed. Được phép dùng trong […]
\n|Có nghĩa là ký tự dòng mới. Được phép dùng trong […]
\r|Có nghĩa là ký tự về đầu dòng. Được phép dùng trong […]
\s|Có nghĩa là tất cả các dấu cách trắng, tức dấu cách, TAB, form-feed, .... Tương đương với "[ \f\n\r\t\v]". Được phép dùng trong […]
\S|Có nghĩa là tất cả các ký tự trừ các dấu cách trắng. Tương đương với "[^ \f\n\r\t\v]"
\t|Có nghĩa là ký tự TAB. Được phép dùng trong […]
\v|ký tự điều khiển vertical tab. Được phép dùng trong […]
\w|Tương đương với "[A-Za-z0-9_]". Được phép dùng trong […]
\W|Tương đương với "[^A-Za-z0-9_]".
()\num|Matches num, where num is a positive integer. A reference back to remembered matches. For example, "(.)\1" matches two consecutive identical characters.
\n|Matches n, where n is an octal escape value. Octal escape values must be 1, 2, or 3 digits long. For example, "\11" and "\011" both match a tab character. "\0011" is the equivalent of "\001" & "1" Octal escape values must not exceed 256. If they do, only the first two digits comprise the expression. Allows ASCII codes to be used in regular expressions.
\xFF với FF là 2 ký tự hệ 16|khớp với ký tự có điểm mã là FF. vd. "\x41" khớp với ký tự "A", "\x041" khớp với "\x04" & "1". Được phép dùng trong […]

Thiết lập mặc định là "tham lam" (Greedy), tức tìm những đoạn dài nhất có thể mà khớp với mẫu. Nếu ta muốn tìm những đoạn ngắn nhất có thể mà khớp với mẫu thì thay vì *, +, ?, {n,}, {n,m} ta dùng phiên bản "lười biếng" (Lazy) của chúng: *?, +?, ??, {n,}?, {n,m}?
e đang nghiên cứu món Pattern này mà đọc đến bài của bác muốn tung não quá :))) nhưng thực sự nó rất chi tiết, rất cám ơn sự nhiệt tình của bác! ^^^^
 
Upvote 0
Lâu quá mình quên hết rồi, giờ mình muốn replace dãy 123(x)456(y)789(z) ... thành 123+456+789, trong đó x,y,z,.. là những con số có các chữ số, vậy Pattern là gì? Nhờ các bạn giúp!. Mình muốn vừa rep vừa tính biểu thức và tìm x,y,z luôn.
 
Lần chỉnh sửa cuối:
Upvote 0
Lâu quá mình quên hết rồi, giờ mình muốn replace dãy 123(x)456(y)789(z) ... thành 123+456+789, trong đó x,y,z,.. là những con số có các chữ số, vậy Pattern là gì? Nhờ các bạn giúp!. Mình muốn vừa rep vừa tính biểu thức và tìm x,y,z luôn.
Gợi nhớ để bạn tự làm:
Cách 1. Tạo pattern với các group và .Replace(Text, "$1+$2+$3")
Cách 2. Global =True pattern = "\(\w{1}\)" .Replace(Text, "+")
 
Upvote 0
Lâu quá mình quên hết rồi, giờ mình muốn replace dãy 123(x)456(y)789(z) ... thành 123+456+789, trong đó x,y,z,.. là những con số có các chữ số, vậy Pattern là gì? Nhờ các bạn giúp!. Mình muốn vừa rep vừa tính biểu thức và tìm x,y,z luôn.
Mã:
Sub abcd()
Dim Str, Cong, Xyz
Str = "123(x)456(y)789(z)"
With CreateObject("vbscript.regexp")
    .Global = True
    .Pattern = "(\d+)(\([^\)]+\))"
    Cong = Evaluate(.Replace(Str, "+" & "$1"))
    Xyz = .Replace(Str, "$2" & " ")
End With
[a1] = Cong
[a2] = Xyz
End Sub
 
Upvote 0
Cám ơn hai bạn HeSanbiCHAOQUAY, mình vừa được cần câu vừa được cá mang về, giờ chỉ còn học cách câu!:)
 
Upvote 1
Web KT
Back
Top Bottom