Đánh giá chủ đề:
  • 0 Votes - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[Thủ Thuật] Tìm, thay thế chuỗi với công cụ RegEx
#1
Trong quá trình giúp đỡ các bạn trong dự án tạo các đề xuất sinh kế, từ các phiếu hỏi được nhập vào một công cụ excel sau đó xuất ra văn bản Word với chế độ định dạng phức tạp, tôi có sáng tác ra một thủ thuật nhỏ để thực hiện điều này. File Word đính kèm là một ví dụ.

Yêu cầu:::
Trong văn bản có các đoạn văn và trong các đoạn văn đó có kiểu định dạng phức hợp, đôi khi giữa dòng lại có một chữ in đậm, in nghiêng hoặc chữ to nhỏ khác nhau.

Giải pháp
Nếu sử dụng các thủ thuật thông thường, đây sẽ là nhiệm vụ cực kỳ phức tạp. Tôi xin giới thiệu một cách tiếp cận linh hoạt học từ cách các diễn đàn thảo luận người ta thường làm bằng cách định nghĩa từ khóa định dạng.
Ví dụ: nếu tôi muốn in đậm chữ/ cụm chữ nào, tôi đặt cụm đó trong khóa <bold>từ khóa cần in đậm</bold>. Tương tự như vậy đối với chữ in nghiêng, gạch chân. Tiếp cận này được gọi là định dạng trực tiếp.
Đôi khi tôi muốn chữ to, chữ nhỏ, giải pháp là đặt thẻ <size=12>từ khóa cần có cỡ chữ khác</size>.

Ngoài ra có cách định dạng phức hợp khác vừa phải cỡ chữ, vừa phải đặt phông chữ đậm, nghiêng. ...
tôi áp dụng từ khóa <style:b=true;i=true;u=true;size=12;>Từ khóa cần định dạng</style>
Tiếp cận này được gọi là đặc tả định dạng gián tiếp.

Bây giờ vấn đề là sẽ đặt các đoạn text với những cụm quy định như vậy, sau đó sử dụng công cụ của word để làm 2 việc:
1. Tìm chuỗi có chứa định dạng trực tiếp, thiết lập định dạng, sau đó xóa từ khóa.
2. Tìm chuỗi có chứa định dạng gián tiếp, đọc tham số định dạng, thiết lập định dạng và xóa bỏ thẻ định dạng.
Để hiểu thêm, các bạn có thể tham khảo tài liệu ví dụ đính kèm dưới đây
Trong tập tin Word này có 2 module
1. Thư viện lớp để loại bỏ từ khóa;
2. Module thực hiện áp đặt định dạng trực tiếp và gián tiếp.
Các bạn muốn xem thông tin có thể nhấn Alt+F11 và xem mã nguồn. Đặt con trỏ vào thủ tục TestX và nhấn F5, các bạn sẽ thấy văn bản được định dạng như ý.

Chúc các bạn sử dụng được thủ thuật này trong các dự án của mình.
(Nếu các bạn muốn tìm hiểu sâu hơn thì xin tải toàn bộ dự án tại địa chỉ http://www.sfdp.net/sedp/nmprp2/dxsk192/...ects=0&d=1, cài đặt và chạy thử nhé)


File đính kèm
.zip   TTthẩm định DT.zip (Kích cỡ: 24.54 KB / Tải về: 57)
Chữ ký của paulsteigel ====================
Quốc gia hưng vong
Thất phu hữu trách
====================
Reply
Những người đã cảm ơn Noname , Minh Tiên , MatTroiNguQuen
#2
Phần 1: Các lệnh xử lý chuỗi thông thường
Trong thao tác với chuỗi ký tự, nhu cầu xử lý chuỗi, tìm kiếm, thay thế thật đa dạng và thật khó có một hướng dẫn nào đáp ứng được hết yêu cầu. Hôm nay, tôi xin phép được viết một cách tóm tắt về chuỗi, xử lý chuỗi với một công cụ tương đối mạnh đó là RegEx.
Trước khi đi vào công cụ này, ta hãy dừng chút thời gian với các cách làm hiện tại:
1. Bộ lệnh và hàm thông thường trong xử lý chuỗi.
Có nhiều nhóm hàm khác nhau nhưng những hàm nổi tiếng phải nói đến là (dấu * có ý là tham số không bắt buộc - optional):
+ Nhóm trích xuất số liệu
- LEFT([Str: Chuỗi cần xử lý],[Length: Chiều dài chuỗi cần lấy]): Trích lấy đoạn ký tự có chiều dài Length từ phía trái đoạn ký tự ban đầu Str.
- RIGHT([Str: Chuỗi cần xử lý],[Length: Chiều dài chuỗi cần lấy]): Tương tự hàm LEFT nhưng lấy từ bên phải
- MID([Str: Chuỗi cần xử lý],[Start: Ký tự bắt đầu trong chuỗi],[*Length: Chiều dài chuỗi cần xử lý]): Trả về chuỗi có chiều dài là Length bắt đầu từ ký tự Start trong chuỗi ban đầu Str. Nếu bỏ qua tham số Length, hàm này sẽ trả về phần còn lại của chuỗi bắt đầu từ ký tự số Start.

+ Nhóm tìm kiếm, kiểm tra, thay thế
- INSTR([*Start: số thứ tự ký tự bắt đầu của chuỗi gốc],[String1: Chuỗi gốc],[String2: chuỗi cần tìm trong chuỗi gốc],[*Compare: cách so sánh chuối, có 2 chế độ - so sánh dạng Text thông thường hoặc so sánh dạng nhị phân]): Trả về giá trị số đặc tả vị trí đầu tiên bắt đầu phát hiện được chuỗi String2 có trong chuỗi String1. Nếu không tìm thấy sẽ trả về 0.
Hàm INSTR là tìm xuôi từ đầu chuỗi và ngược lại có hàm INSTRREV tìm ngược từ cuối chuỗi.
- INSTRREV([StringCheck: Chuỗi cần kiểm tra],[StringMatch: Chuỗi cần tìm],[*Start: Điểm bắt đầu tìm kiếm tính từ bên trái, nếu bỏ qua, hàm sẽ tìm từ vị trí cuối cùng bên phải chuỗi kiểm tra và giảm dần từ phải qua trái],[*Compare: tương tự như Instr])
- REPLACE(

[Expression: Chuỗi có chứa chuỗi con cần thay thế], [Find: Chuỗi con cần tìm để thay thế], [Replacement: Chuỗi thay thế cho chuỗi con],[*Start: Vị trí trong chuỗi tìm kiếm ấn định chỗ bắt đầu tìm, nếu bỏ qua, hàm sẽ bắt đầu tìm từ 1],[*Count: Số lần thay thế cần thực hiện. Nếu bỏ qua, giá trị mặc định là -1 và hàm sẽ thay thế tất cả các chuỗi phát hiện được], [*Compare: tương tự như đối với các hàm Instr, InstrRev)

Vâng chỉ với bộ hàm này chúng ta đã có thể làm được rất nhiều việc trong xử lý chuỗi, đặc biệt là nhóm Instr/InstrRev và Replace. Chẳng hạn:
1. Lọc tên tập tin từ chuỗi chứa đường dẫn đầy đủ của tập tin:
Mã:
Function GetFileName(FullFileName As String) As String
    On Error Resume Next
    GetFileName = Mid(FullFileName, InStrRev(FullFileName, "\") + 1)
End Function
Ví dụ: chuỗi chứa đường dẫn đầy đủ là "C:\Program Files\7-Zip\7zG.exe"
Mã:
Debug.Print GetFileName("C:\Program Files\7-Zip\7zG.exe")
Kết quả sẽ là 7zG.exe
Hàm sẽ tìm từ bên phải đối với ký tự "\" và trả về vị trí tìm được đầu tiên, sau đó hàm Mid sẽ lấy luôn giá trị tìm được.

2. Đếm số lần xuất hiện chuỗi nào đó trong chuỗi cho trước
Cho 2 chuỗi 
x = "html,xlsx,xltx,potx,ppsx,pptx,docx,dotx" ' liệt kê danh sách các phần đuôi của file
y = "text/html,Excel document,Excel Template,PowerPoint Template,PowerPoint Script,Word Document,Word Template" ' liệt kê phần mô tả kiểu file ứng với đuôi file ở trên.

Hãy tìm kiểu file tương ứng từ phần mở rộng của file mà không cần dùng tới vòng lặp
trong đa số các trường hợp, chúng ta sẽ luôn bắt đầu bằng việc xây dựng 2 mảng thông qua lệnh Split sau đó dùng vòng lặp để duyệt qua mảng chứa các phần tử của chuỗi 1 sau đó so sánh và trả về giá trị tương ứng ở mảng chứa các phần tử chuỗi 2.

Nếu không dùng vòng lặp thì làm thế nào? Các bạn hãy xem hàm sau đây (được dùng để trả về kiểu file tương ứng dựa vào phần mở rộng của file)

Mã:
Function GetMimeType(FileExtension As String) As String
    Dim x As String, y As string, z As String, xPos As Long
    Dim tmpStr As String
    x = "html,xlsx,xltx,potx,ppsx,pptx,docx,dotx"
    y = "text/html,Excel document,Excel Template,PowerPoint Template,PowerPoint Script,Word Document,Word Template"

    xPos = InStr(x & ",", LCase(FileExtension) & ",") ' Các bạn chú ý tôi gắn thêm 1 dấu phẩy vào cuối chuỗi cần tìm
    
    If xPos > 0 Then
        ' tìm được vị trí bắt đầu xuất hiện chuỗi
        tmpStr = Left(x, xPos - 1)' lấy phần chuỗi gốc từ đấu đến vị trí tìm thấy
        xPos = Len(tmpStr) - Len(Replace(tmpStr, ",", "")) ' đếm xem có bao nhiêu dấu phẩy bị thay thế và ứng với nó chính là số thứ tự của phần tử trong mảng ở câu lệnh ngay dưới đây
        GetMimeType = Split(y,",")(xPos)
    Else
        GetMimeType = "application/vnd.google-apps.unknown"
    End If
End Function

Đấy là một vài kiểu ví dụ. Các bạn có thể thấy là khá đủ để xử lý các công việc đơn giản với chuỗi. Nhưng với các yêu cầu khác như: tác riêng số ra khỏi chuỗi, tách riêng các đoạn ký tự nằm trong chuỗi đặc biệt nào đó ví dụ đối với chuỗi chứa văn bản HTML thì việc dùng các hàm này sẽ khó khăn hơn nhiều. Bài sau tôi sẽ trình bày về công cụ RegEx.
Xin chân thành cảm ơn
Chữ ký của paulsteigel ====================
Quốc gia hưng vong
Thất phu hữu trách
====================
Reply
Những người đã cảm ơn Minh Tiên , Noname , MatTroiNguQuen , Che_Guevara , maidinhdan


Có thể liên quan đến chủ đề
Chủ đề: Tác giả Trả lời: Xem: Bài mới nhất
  Về việc lập trình truy xuất thông tin từ cổng RS232 trong Access VBA lehongduc 0 132 23-05-16, 11:43 AM
Bài mới nhất: lehongduc
  Xây dựng các chuổi tham chiếu lồng ghép có dấu ngoặc kép tranthanhan1962 4 785 31-07-15, 11:27 PM
Bài mới nhất: tranthanhan1962
  Hướng Dẫn MZTool 3.0 - Công cụ hỗ trợ soạn code VBA nhanh và dễ maidinhdan 2 767 29-07-15, 03:11 PM
Bài mới nhất: maidinhdan
  [Hỏi] Thay đổi màu label khi di chuyển hugox03 4 591 18-11-14, 12:28 AM
Bài mới nhất: hugox03
  hàm thay thế chọn TimerInterval trên forms hugox03 3 665 05-03-14, 01:50 AM
Bài mới nhất: hugox03

Chuyển nhanh:


User(s) browsing this thread: 1 Guest(s)
Diễn Đàn Thơ Văn Thi Ẩm Lâu|Nhà Hàng Sông Thơ