Hướng dẫn [Regex-function] Công cụ lưu trữ Regex hiệu quả

Thảo luận trong 'Hướng dẫn chung' bắt đầu bởi inno14, 3/9/20.

  1. inno14

    inno14 Lớp 8

    * Mình được một bạn nhắn cho như thế này:
    * Câu hỏi đắt nhất ở đúng câu cuối cùng và kết quả là có bài này :)
    1. Đầu tiên là lời giải cho phần câu hỏi đến trước câu cuối cùng:
    Tìm: (<h.*?>.*?</h.*?>\s*)(<p.*?>)(\p{L})(.*?</p>)
    Thay thế ở chế độ Regex: \1<p><span class="drop">\3</span>\4
    01.png
    02.png

    2. Và đây là lời giải cho câu cuối cùng:
    Mã:
    #Find: (<h.*?>.*?</h.*?>\s*)(<p.*?>)(\p{L})(.*?</p>)
    def replace(match, number, file_name, metadata, dictionaries, data, functions, *args,
    **kwargs):
        return match.group(1)+'<p><span class="drop">'+match.group(3)+'</span>'+match.group(4)
    
    # Ensure that when running over multiple files, the files are processed
    # in the order in which they appear in the book
    replace.file_order = 'spine'
    03.png
    * Mục đích của việc tạo Function để làm gì? Đó là lưu trữ cú pháp tìm kiếm và thay thế để dùng lại cho các trường hợp tương tự ở những ebook khác một cách nhanh chóng, và có thể chia sẻ cho một người dùng khác sử dụng mà không cần biết về regex.
    * Sự quy ước để chuyển đổi từ regex sang regex-function
    1. \1 sẽ tương ứng với match.group(1) tương tự với \2 \3...
    2. Phép nối text là phép +
    3. Cụm text trên cùng 1 hàng được đặt giữa 2 dấu '. Ví dụ 'abc'
    4. Cụm text có nhiều dòng sẽ được đặt giữa 2 dấu '''. Ví dụ:
    '''abc
    xyz'''
    5. Kết quả trả về luôn đặt sau lệnh return
    6. replace.file_order = 'spine' là lệnh replace sẽ thực thi trên tất cả html có trong ebook
    7. #Find: là ghi chú cú pháp tìm kiếm để copy và dán vào ô Find khi sử dụng mà không cần gõ lại.
    ===
    Chúc các bạn làm sách vui vẻ :)
     
    amylee, ntdieu, Gold.ball and 5 others like this.
  2. inno14

    inno14 Lớp 8

    * Mình lại nhận được 1 câu hỏi về cập nhật Function
    * thực ra cái cần cập nhật lúc này không phải là cấu trúc return mà là cấu trúc #Find, lúc này chúng ta sẽ sử dụng hàm or (dấu |) để regex thực hiện việc tìm kiếm
    * Function mới sẽ như thế này (thực ra vẫn là phép thay thế cũ, chỉ cập nhật cho phép tìm kiếm)
    Mã:
    #Find: (<h.*?>.*?</h.*?>\s*)(<p.*?>)(\p{L}|[\" \“]\p{L})(.*?</p>)
    def replace(match, number, file_name, metadata, dictionaries, data, functions, *args,
    **kwargs):
        return match.group(1)+'<p><span class="drop">'+match.group(3)+'</span>'+match.group(4)
    
    # Ensure that when running over multiple files, the files are processed
    # in the order in which they appear in the book
    replace.file_order = 'spine'
    * Ở cấu trúc tìm kiếm mới này chúng ta thấy \3 đã thay đổi khi từ (\p{L}) thành (\p{L}|[\" \“]\p{L}) tức là thay vì \3 lúc đầu chỉ là 1 ký tự unicode thì lúc này \3 (match.group(3)) đã trở thành 1 ký tự unicode, hoặc dấu " và 1 ký tự unicode hoặc dấu “ và 1 ký tự unicode. Chúng ta chỉ cần thay đổi cấu trúc tìm kiếm một chút để \3 chứa nhiều kiểu dữ liệu hơn thôi mà không cần thay đổi phép thay thế.
    * Lưu ý một bộ (...) được đếm từ trái qua phải tương ứng \1 \2 \3.... ở regex thì khi lưu vào function nó tương ứng với match.group(1), match.group(2), match.group(3).... do đó phép nối text sẽ phụ thuộc vào số bộ (...) các bạn chia cấu trúc text gốc.
    * Ở phép thay thế này chúng ta thấy \2 là cái cần thay thế thành một cụm text mới nên ở cấu trúc return sẽ không dùng lại \2 nữa.
     
  3. inno14

    inno14 Lớp 8

    Mình post lại một số quy ước khi sử dụng regex.
     
    Chỉnh sửa cuối: 3/9/20
  4. vinaguy

    vinaguy Lớp 11

    Báo cáo Thầy INNO! Học trò của Thầy đã lĩnh hội được tất cả những gì Thầy muốn chuyển tải ở trên đây để áp dụng cho tất cả các trường hợp rồi Thầy nhé. Cám ơn Thầy rất nhiều ạ! Nếu ở gần thì phải đãi Thầy cái gì mới được :D:D:D
     
    tran ngoc anh and inno14 like this.
  5. mrb26

    mrb26 Mầm non

    Chào các bác cho em hỏi: Em muốn count dòng đầu tiên ( DropCap ) ngắn quá thì đánh dấu vào nhưng viết Function không chạy. Nhờ các bác chỉ giúp
    Mã:
    #Find: (</span>.*?)(</p>)
    def replace(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
        sochu = len(group(1))
        if (sochu < 100)
        return match.group(1) + "9999" + match.group(2)
        else
        return match.group(1) + match.group(2)
    replace.file_order = 'spine'
    Thanks các bác !
     
  6. vinaguy

    vinaguy Lớp 11

    upload_2022-12-22_14-0-35.png
    Em chưa thử function này. Có khi nào sai chỗ chữ "len" không bác? Thường trong tiếng Anh thì "length" này chứ nhỉ? Bác kiểm tra lại câu lệnh xem?
     
    mrb26 thích bài này.
  7. tran ngoc anh

    tran ngoc anh Cử nhân

    Không rõ bạn ấy cần count là đếm số dòng dropcap hay đếm số từ trong mỗi dòng dropcap?
     
  8. powertalent

    powertalent Mầm non

    Mã:
    def replace(match, number, file_name, metadata, dictionaries, data, functions, *args, **kwargs):
        sochu = len(match.group(1))
        if sochu < 100:
            return match.group(1) + "9999" + match.group(2)
        else:
            return match.group(1) + match.group(2)
    replace.file_order = 'spine'
    
    
     
    pTalent and mrb26 like this.
  9. vinaguy

    vinaguy Lớp 11

    Em nghĩ nó đếm tất cả (</span>.*?)(</p>), từ "</" đến "p>" luôn đó bác.
     
  10. mrb26

    mrb26 Mầm non

    Em đếm số chữ trong dòng có DropCap để chỉnh sửa vì dòng có DropCap mà ngắn quá hiển thị rất xấu nên gộp dòng
     
    tran ngoc anh thích bài này.
  11. mrb26

    mrb26 Mầm non

    Cũng không được bác ah, tài liệu hướng dẫn cái này trên mạng ít đến đáng thương :D
     
  12. mrb26

    mrb26 Mầm non

    Thanks bác đã chạy :D
     
    Chỉnh sửa cuối: 22/12/22
    vinaguy thích bài này.
  13. powertalent

    powertalent Mầm non

    Cái này nó viết bằng python, mấy bác muốn tìm hiểu thì tìm hiểu python
    Vui lòng đăng nhập hoặc đăng ký để xem link
    Vui lòng đăng nhập hoặc đăng ký để xem link
     
    pTalent, vinaguy and mrb26 like this.

Chia sẻ trang này