Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Lập Trình Bash

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Biểu thức chính quy là gì?

Biểu thức chính quy, còn được gọi là biểu thức chính quy, hoạt động bằng cách xác định các mẫu mà bạn có thể sử dụng để tìm kiếm các ký tự hoặc từ nhất định trong chuỗi.

Sau khi xác định mẫu bạn muốn sử dụng, bạn có thể thực hiện chỉnh sửa, xóa một số ký tự hoặc từ nhất định, thay thế nội dung này bằng nội dung khác, trích xuất thông tin liên quan từ một tệp hoặc bất kỳ chuỗi nào chứa mẫu cụ thể đó, v.v.

Tại sao bạn nên học Regex?

Regex cho phép bạn xử lý văn bản theo cách có thể giúp bạn tiết kiệm rất nhiều thời gian. Nó cũng có thể mang lại một số điều thú vị trong quá trình này.

Sử dụng biểu thức chính quy có thể giúp việc định vị thông tin dễ dàng hơn nhiều. Sau khi tìm thấy mục tiêu của mình, bạn có thể chỉnh sửa/thay thế/xóa hàng loạt hoặc bất kỳ quá trình xử lý nào bạn cần thực hiện.

Một số ví dụ thực tế về việc sử dụng biểu thức chính quy là đổi tên tệp hàng loạt, phân tích cú pháp nhật ký, xác thực biểu mẫu, thực hiện chỉnh sửa hàng loạt trong cơ sở mã và tìm kiếm đệ quy.

Trong hướng dẫn này, chúng ta sẽ đề cập đến những vấn đề cơ bản về Regex với sự trợ giúp của trang web này. Sau này, tôi sẽ giới thiệu một số thách thức về biểu thức chính quy mà bạn sẽ giải quyết bằng Python. Tôi cũng sẽ chỉ cho bạn cách sử dụng các công cụ như sedgrep bằng biểu thức chính quy.

Giống như nhiều thứ trong cuộc sống, biểu thức chính quy là một trong những thứ mà bạn chỉ có thể thực sự hiểu được bằng cách thực hiện. Tôi khuyến khích bạn thử nghiệm với biểu thức chính quy khi bạn đang xem qua bài viết này.

Mục lục

  • Cơ bản về Regex
    • Kết hợp chính xác
    • Bộ ký tự
      • So khớp phạm vi trong biểu thức chính quy
      • Khớp bất kỳ ký tự nào không có trong bộ
    • Các lớp nhân vật
    • Bộ định lượng
    • Thu thập nhóm
      • Cách sử dụng logic OR trong biểu thức chính quy
      • Cách tham khảo các nhóm chụp
      • Cách đặt tên nhóm chụp
  • Cách sử dụng biểu thức chính quy với các công cụ dòng lệnh
    • Tìm kiếm biểu thức chính quy đệ quy bằng grep
    • Thay thế bằng sed
  • regex nâng cao:Nhìn lại
    • Nhìn lại
    • Tầm nhìn
  • Ví dụ thực tế về Regex
    • Phân tích cú pháp nhật ký
    • Đổi tên tệp hàng loạt
    • Xác thực email
    • Hạn chế mật khẩu
  • Lời cuối cùng

Thông tin cơ bản về Regex

Biểu thức chính quy không là gì ngoài một chuỗi ký tự khớp với một mẫu. Ngoài việc sử dụng các ký tự chữ (như 'abc'), còn có một số ký tự meta (*,+,?, v.v.) có mục đích đặc biệt. Ngoài ra còn có các tính năng như lớp ký tự có thể giúp bạn đơn giản hóa các biểu thức thông thường của mình.

Trước khi viết bất kỳ biểu thức chính quy nào, bạn cần tìm hiểu về tất cả các trường hợp cơ bản và trường hợp đặc biệt cho mẫu bạn đang tìm kiếm.

Ví dụ:nếu bạn muốn khớp với 'Xin chào thế giới', bạn muốn dòng bắt đầu bằng 'Xin chào' hay nó có thể bắt đầu bằng bất cứ điều gì? Bạn muốn có chính xác một khoảng trắng giữa 'Xin chào' và 'Thế giới' hay có thể có nhiều khoảng cách hơn? Các nhân vật khác có thể đến sau 'World' hay dòng này nên kết thúc ở đó? Bạn có quan tâm đến phân biệt chữ hoa chữ thường không? Và vân vân.

Đây là những loại câu hỏi mà bạn phải có câu trả lời trước khi bắt đầu viết biểu thức chính quy của mình.

Kết hợp chính xác

Dạng biểu thức chính quy cơ bản nhất bao gồm việc khớp một chuỗi ký tự theo cách tương tự như bạn có thể làm với Ctrl-F trong trình soạn thảo văn bản.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Ở trên cùng, bạn có thể thấy số lượng kết quả khớp và ở phía dưới có phần giải thích về những gì biểu thức chính quy khớp với từng ký tự.

Bộ ký tự

Bộ ký tự Regex cho phép bạn khớp bất kỳ ký tự nào trong một nhóm ký tự. Nhóm được bao quanh bởi dấu ngoặc vuông [].

Ví dụ:t[ah]i khớp với "tai" và "thi". Ở đây 't' và 'i' là cố định nhưng giữa chúng có thể xảy ra 'a' hoặc 'h'.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

So khớp phạm vi trong biểu thức chính quy

Đôi khi bạn có thể muốn khớp một nhóm ký tự có tính chất tuần tự, chẳng hạn như bất kỳ chữ cái tiếng Anh viết hoa nào. Nhưng viết hết 26 chữ cái sẽ khá tẻ nhạt.

Regex giải quyết vấn đề này bằng phạm vi. "-" hoạt động như một toán tử phạm vi. Một số phạm vi hợp lệ được hiển thị bên dưới:

Phạm vi phù hợp [A-Z]chữ hoa[a-z]chữ thường[0-9]Chữ số bất kỳ

Bạn cũng có thể chỉ định một phần phạm vi, chẳng hạn như [b-e] để khớp với bất kỳ chữ cái nào 'bcde' hoặc [3-6] để khớp với bất kỳ số nào '3456'.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bạn không bị giới hạn chỉ xác định một phạm vi bên trong một bộ ký tự. Bạn có thể sử dụng nhiều phạm vi và cũng có thể kết hợp chúng với bất kỳ ký tự bổ sung nào khác. Đây, [3-6u-w;] sẽ khớp với bất kỳ '3456uvw' hoặc dấu chấm phẩy ';' nào.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Khớp bất kỳ ký tự nào không có trong bộ

Nếu bạn thêm '^' vào tiền tố tập hợp, thao tác nghịch đảo sẽ được thực hiện. Ví dụ:[^A-Z0-9] sẽ khớp với mọi thứ ngoại trừ chữ in hoa và chữ số.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Các lớp nhân vật

Trong khi viết biểu thức chính quy, bạn sẽ cần phải khớp các nhóm nhất định như chữ số khá thường xuyên và nhiều lần trong cùng một biểu thức.

Vì vậy, ví dụ:bạn sẽ khớp mẫu như 'chữ-chữ-chữ-chữ số' bằng cách nào?

Với những gì bạn đã học được cho đến bây giờ, bạn có thể nghĩ ra [a-zA-Z]-[0-9]-[a-zA-z]-[0-9] . Cách này hiệu quả nhưng bạn có thể thấy biểu thức có thể trở nên khá lộn xộn khi độ dài mẫu ngày càng lớn.

Để làm cho biểu thức đơn giản hơn, các lớp đã được gán cho các nhóm ký tự được xác định rõ ràng chẳng hạn như các chữ số. Bảng sau đây hiển thị các lớp này và biểu thức tương đương của chúng với các bộ ký tự:

ClassMatchesBiểu thức tương đương .bất cứ thứ gì ngoại trừ dòng mới[^\n\r]\wword character[a-zA-Z0-9_]\Wnon-word character[^\w]\ddigits[0-9]\Dnon-digits[^\d]\sspace, tab, newlines[ \t\r\n\f]\Snon các ký tự khoảng trắng[^\s]

Các lớp nhân vật khá tiện dụng và làm cho biểu cảm của bạn rõ ràng hơn nhiều. Chúng tôi sẽ sử dụng chúng một cách rộng rãi trong suốt hướng dẫn này, vì vậy bạn có thể sử dụng bảng này làm điểm tham khảo và quay lại đây nếu bạn quên bất kỳ lớp nào.

Hầu hết chúng ta sẽ không quan tâm đến tất cả các vị trí trong một mẫu. Dấu "." lớp giúp chúng ta không phải viết tất cả các ký tự có thể có trong một tập hợp.

Ví dụ:t.. khớp với bất cứ thứ gì bắt đầu bằng t và hai ký tự bất kỳ sau đó. Điều này có thể khiến bạn nhớ đến LIKE SQL toán tử sẽ sử dụng t%% để hoàn thành điều tương tự.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bộ định lượng

Từ "mẫu" và "sự lặp lại" đi đôi với nhau. Nếu bạn muốn khớp một số có 3 chữ số, bạn có thể sử dụng \d\d\d . Nhưng nếu bạn cần khớp 11 chữ số thì sao? Bạn có thể viết '\d' 11 lần, nhưng một nguyên tắc chung khi viết biểu thức chính quy hoặc chỉ thực hiện bất kỳ loại lập trình nào là nếu bạn thấy mình lặp lại điều gì đó nhiều hơn hai lần, có thể bạn không biết về một số tính năng.

Trong biểu thức chính quy, bạn có thể sử dụng bộ định lượng cho mục đích này. Để khớp 11 chữ số, bạn chỉ cần viết biểu thức \d{11} .

Bảng bên dưới liệt kê các bộ định lượng bạn có thể sử dụng trong biểu thức chính quy:

Số lượng phù hợp *0 trở lên?0 hoặc 1+1 trở lên{n}chính xác n lần{n, }n lần trở lên{n, bao gồm m}n đến m lần

Trong ví dụ này, biểu thức can\s+write khớp với can theo sau là 1 hoặc nhiều khoảng trắng, theo sau là write . Nhưng bạn có thể thấy 'canwrite' không khớp với \s+ có nghĩa là ít nhất một khoảng trắng cần phải khớp. Điều này hữu ích khi bạn đang tìm kiếm trong văn bản chưa được cắt bớt.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bạn có đoán được can\s?write là gì không? sẽ phù hợp?

Thu thập nhóm

Nhóm chụp là các biểu thức phụ được đặt trong dấu ngoặc đơn (). Bạn có thể có bất kỳ số lượng nhóm chụp nào và thậm chí cả các nhóm chụp lồng nhau.

Biểu thức (The ){2} khớp với 'The ' hai lần. Nhưng không có nhóm chụp, biểu thức The {2} sẽ khớp với 'The' theo sau là 2 dấu cách, vì bộ định lượng sẽ được áp dụng trên ký tự dấu cách chứ không phải trên 'The ' dưới dạng một nhóm.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bạn có thể khớp bất kỳ mẫu nào trong các nhóm chụp giống như với bất kỳ biểu thức chính quy hợp lệ nào. Đây (is\s+){2} khớp nếu tìm thấy 'is' theo sau bởi 1 hoặc nhiều dấu cách hai lần.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Cách sử dụng logic OR trong biểu thức chính quy

Bạn có thể sử dụng "|" để phù hợp với nhiều mẫu. This is (good|bad|sweet) khớp với 'Đây là' theo sau là bất kỳ từ 'tốt', 'xấu' hoặc 'ngọt ngào' nào.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Một lần nữa, bạn phải hiểu tầm quan trọng của các nhóm bắt giữ ở đây. Hãy suy nghĩ về biểu thức This is good|bad|sweet có phù hợp không?

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Với một nhóm bắt giữ, good|bad|sweet bị cô lập khỏi This is . Nhưng nếu nó không nằm trong nhóm chụp thì toàn bộ biểu thức chính quy chỉ là một nhóm. Vì vậy biểu thức This is good|bad|sweet sẽ khớp nếu chuỗi chứa 'Điều này tốt' hoặc 'xấu' hoặc 'ngọt'.

Cách tham khảo các nhóm chụp

Các nhóm thu thập có thể được tham chiếu trong cùng một biểu thức hoặc trong khi thực hiện thay thế như bạn có thể thấy trên tab Thay thế.

Hầu hết các công cụ và ngôn ngữ đều cho phép bạn tham chiếu nhóm đã chụp thứ n bằng '\n'. Trong trang này '$n' được sử dụng khi tham chiếu đến việc thay thế. Cú pháp thay thế sẽ khác nhau tùy thuộc vào công cụ hoặc ngôn ngữ bạn đang sử dụng. Ví dụ:đối với JavaScript, đó là '$n', trong khi đối với Python là '\n'.

Trong biểu thức (This) is \1 power , 'Cái này' được ghi lại và sau đó được tham chiếu bằng '\1', khớp hiệu quả với This is This power .

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Cách đặt tên nhóm chụp

Bạn có thể đặt tên cho nhóm chụp của mình bằng cú pháp (?<name>pattern) và phản chiếu chúng trong cùng một biểu thức với \k<name> .

Khi thay thế, việc tham chiếu được thực hiện bởi $<name> . Đây là cú pháp của JavaScript và có thể khác nhau giữa các ngôn ngữ. Bạn có thể tìm hiểu về sự khác biệt ở đây. Cũng xin lưu ý rằng tính năng này có thể không có ở một số ngôn ngữ.

Trong biểu thức (?<lang>[\w+]+) is the best but \k<lang> .* , mẫu [\w+]+ được ghi lại với tên 'lang' và được tham chiếu ngược với \k<lang> . Mẫu này sẽ khớp với bất kỳ ký tự từ hoặc ký tự '+' nào 1 lần trở lên. .* ở cuối biểu thức chính quy khớp với bất kỳ ký tự nào 0 lần trở lên. Và cuối cùng khi thay thế, việc tham chiếu được thực hiện bởi $<lang> .

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Có sẵn các công cụ CLI tốt cho phép bạn thực hiện biểu thức chính quy từ thiết bị đầu cuối của mình. Những công cụ này giúp bạn tiết kiệm nhiều thời gian hơn vì bạn có thể dễ dàng kiểm tra các biểu thức chính quy khác nhau mà không cần viết mã bằng một số ngôn ngữ rồi biên dịch hoặc diễn giải nó.

Một số công cụ nổi tiếng là grep, sed và awk. Hãy xem một số ví dụ để cung cấp cho bạn một số ý tưởng về cách bạn có thể tận dụng những công cụ này.

Tìm kiếm biểu thức chính quy đệ quy với grep

Bạn có thể thực thi sức mạnh của biểu thức chính quy thông qua grep. Grep có thể tìm kiếm các mẫu trong một tệp hoặc thực hiện tìm kiếm đệ quy.

Nếu bạn đang dùng Windows, bạn có thể cài đặt grep bằng winget. Chạy lệnh này trong powershell:

winget install -e --id GnuWin32.Grep

Tôi sẽ chỉ cho bạn giải pháp cho một thử thách mà tôi đã tạo ra cho cuộc thi CTF tại trường đại học của mình.

Tệp đính kèm với thử thách là một tệp zip chứa nhiều cấp độ thư mục và rất nhiều tệp trong đó. Tên cuộc thi là Coderush với định dạng cờ coderush{flag is here} . Vì vậy bạn phải tìm kiếm mẫu coderush{.*} sẽ khớp với định dạng cờ coderush{any character here} .

Giải nén file bằng unzip ripG.zip và cd vào đó bằng cd ripG .

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Có 358 thư mục và 8731 tập tin. Thay vì tìm kiếm từng mẫu trong tệp, bạn có thể sử dụng grep như thế này:

grep --color -R "coderush{.*}"

Cờ "-R" cho phép tìm kiếm đệ quy.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bạn có thể tìm hiểu thêm về grep và các tùy chọn dòng lệnh của nó tại đây

Thay thế bằng sed

Bạn có thể sử dụng sed để thực hiện chèn, xóa, thay thế trên tệp văn bản bằng cách chỉ định biểu thức chính quy. Nếu bạn đang ở trên windows, bạn có thể nhận sed từ đây. Hoặc nếu bạn sử dụng WSL, các công cụ như grep và sed sẽ có sẵn.

Đây là cách sử dụng phổ biến nhất của sed:

sed 's/pattern/replacement/g' filename
echo "${text}" | sed 's/pattern/replacement/g'

Ở đây, tùy chọn "g" được chỉ định để thay thế tất cả các lần xuất hiện.

Một số tùy chọn hữu ích khác là -n để loại bỏ hành vi mặc định là in tất cả các dòng và sử dụng p thay vì g để chỉ in những dòng bị ảnh hưởng bởi biểu thức chính quy.

Chúng ta hãy xem nội dung của text.txt.

Hello rand chars World 56 rand chars
Henlo 52 rand chars W0rld rand chars
GREP rand chars Henlo 62 rand chars
Henlo 10 rand chars Henlo rand chars
GREP rand chars Henlo 45 rand chars

Nhiệm vụ của chúng ta là thay thế Henlo number với Hello number chỉ trong những dòng có "GREP". Vì vậy, chúng tôi đang tìm kiếm mẫu Henlo ([0-9]+) sẽ khớp với 'Henlo', theo sau là 1 chữ số trở lên và tất cả các chữ số đều được ghi lại. Khi đó chuỗi thay thế của chúng ta sẽ là Hello \1 – '\1' đang tham chiếu nhóm chụp có chứa các chữ số.

Một cách để thực hiện điều đó là sử dụng grep để grep các dòng có "GREP" sau đó thực hiện thay thế bằng sed.

grep "GREP" texts.txt | sed -En 's/Henlo ([0-9]+)/Hello \1/p'

Tùy chọn "-E" cho phép mở rộng biểu thức chính quy mà không cần phải thoát khỏi dấu ngoặc đơn.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Hoặc bạn chỉ có thể sử dụng sed. Sử dụng /pattern/ để hạn chế sự thay thế chỉ trên các dòng có mẫu.

sed -En '/GREP/ s/Henlo ([0-9]+)/Hello \1/p' texts.txt

regex nâng cao:Nhìn lại

Lookaheads và Lookbehinds (cùng được gọi là lookaround) là các tính năng của biểu thức chính quy cho phép bạn kiểm tra sự tồn tại của một mẫu mà không đưa nó vào đối sánh.

Bạn có thể coi chúng như những xác nhận có độ rộng bằng 0 – chúng khẳng định sự tồn tại của một mẫu nhưng không sử dụng bất kỳ ký tự nào trong trận đấu. Đây là những tính năng rất mạnh mẽ nhưng chúng cũng tốn kém về mặt tính toán. Vì vậy, hãy đảm bảo bạn theo dõi hiệu suất nếu bạn sử dụng chúng thường xuyên.

Nhìn lại phía sau

Giả sử bạn muốn khớp từ 'linux', nhưng bạn có 2 điều kiện.

  1. Từ 'GNU' phải xuất hiện trước khi xuất hiện 'linux'. Nếu một dòng chứa 'linux' nhưng không có 'GNU' trước nó, chúng tôi muốn loại bỏ dòng đó.
  2. Chúng tôi chỉ muốn khớp linux và không có gì khác.

Chúng ta đã biết cách thỏa mãn điều kiện thứ nhất. GNU.* sẽ khớp với 'GNU' theo sau là bất kỳ số lượng ký tự nào. Sau đó cuối cùng chúng ta ghép từ linux . Điều này sẽ khớp với tất cả GNU-any-characters-linux .

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Nhưng làm cách nào để ngăn chặn việc trùng khớp GNU.* trong khi vẫn duy trì điều kiện thứ nhất?

Đó là lúc cần có một giao diện tích cực. Bạn có thể đánh dấu một nhóm chụp là một giao diện tích cực bằng cách thêm ?<= vào trước nhóm đó. . Trong ví dụ này, biểu thức trở thành (?<=GNU.*)linux .

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bây giờ chỉ có linux được khớp và không có gì khác.

Lưu ý rằng các biểu thức (?<=GNU.*)linuxlinux(?<=GNU.*) sẽ hành xử giống hệt nhau. Trong biểu thức thứ 2, mặc dù linux trước phần nhìn phía sau có .* sau 'GNU' khớp với linux . Điều này có nghĩa là nó đáp ứng được cái nhìn phía sau.

Để đơn giản hơn, hãy nghĩ về mẫu không có phần nhìn phía sau. Mẫu GNU.* sẽ khớp với 'GNU' và bất kỳ thứ gì sau nó, trong trường hợp của chúng tôi khớp với linux .

Bây giờ chúng ta có thể rút ra một phát biểu tổng quát rằng biểu thức (?<=C)X sẽ khớp với mẫu X – chỉ khi mẫu C xuất hiện trước X (và C không được đưa vào mẫu khớp).

Bạn cũng có thể đảo ngược điều kiện thứ nhất. Nối các dòng có chứa từ linux chỉ khi GNU chưa bao giờ đến trước nó. Điều này được gọi là một cái nhìn tiêu cực phía sau. Tiền tố trong trường hợp này là ?<! . Nghịch đảo của biểu thức trước đó sẽ là (?<!GNU.*)linux .

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Tầm nhìn

Lookaheads cũng là những xác nhận giống như lookbehinds, như bạn đã thấy trong ví dụ trước. Sự khác biệt duy nhất là cái nhìn phía sau đưa ra xác nhận trước và cái nhìn phía trước đưa ra xác nhận sau.

Giả sử bạn có hai điều kiện sau:

  1. Trùng khớp với Hello chỉ khi World sẽ xuất hiện ở đâu đó sau nó.
  2. Chỉ khớp với Hello và không có gì khác.

Tiền tố cho một cái nhìn tích cực là ?= . Biểu thức Hello(?=.*World) sẽ đáp ứng cả hai điều kiện. Điều này tương tự với Hello.*World ngoại trừ việc chỉ có Hello sẽ được khớp trong khi Hello.*World sẽ khớp với 'Xin chào', 'Thế giới' và bất cứ thứ gì ở giữa.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Tương tự như ví dụ ở phía sau tích cực, các biểu thức Hello(?=.*World)(?=.*World)Hello là tương đương. Bởi vì .* trước khi 'Thế giới' khớp với Hello , thỏa mãn điều kiện thứ nhất.

Một cái nhìn tiêu cực về phía trước chỉ là sự bổ sung cho một cái nhìn tiêu cực về phía sau. Bạn có thể sử dụng nó bằng cách thêm tiền tố ?! . (?!World)Hello sẽ khớp với Hello chỉ khi không có World bất cứ nơi nào sau nó.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Dưới đây là bản tóm tắt cú pháp để xem xét khi bạn muốn khớp mẫu X với xác nhận C.

Hoạt độngRegEx cái nhìn tích cực(?=C)X cái nhìn tiêu cực(?!C)X cái nhìn tích cực(?<=C)X cái nhìn tiêu cực(?<!C)X

Phân tích nhật ký

Trong tệp nhật ký này, đây là những dòng chúng tôi quan tâm:

[1/10000] Train loss: 11.30368, Valid loss: 8.95446, Elapsed_time: 7.58941
[500/10000] Train loss: 0.96180, Valid loss: 0.20098, Elapsed_time: 82.48651
[1000/10000] Train loss: 0.04051, Valid loss: 0.11927, Elapsed_time: 156.86243

Nhiệm vụ của chúng tôi là trích xuất tổn thất huấn luyện và tổn thất xác nhận cho các mục đích như lập biểu đồ tổn thất theo các kỷ nguyên. Chúng ta cần trích xuất các giá trị mất huấn luyện như 11.30368, 0.96180, 0.04051 và đặt chúng vào một mảng.

Tất cả các giá trị liên quan đều có tiền tố 'Train loss: ', vì vậy chúng ta có thể sử dụng điều này trong biểu thức chính quy của mình. Để khớp với các số thực, chúng ta phải khớp một số chữ số theo sau là ". " và sau đó là nhiều chữ số hơn. Bạn có thể làm điều này với \d+\.\d+ . Bởi vì chúng tôi muốn theo dõi những con số này nên chúng phải nằm trong một nhóm bắt giữ.

Là "." có mục đích đặc biệt trong biểu thức chính quy, khi bạn muốn khớp với "." ký tự bạn phải thoát nó bằng dấu gạch chéo ngược. Điều này áp dụng cho tất cả các ký tự có mục đích đặc biệt. Nhưng bạn không cần phải thoát nó trong bộ ký tự.

Nói chung, biểu thức để trích xuất mất mát đào tạo là Train loss: (\d+\.\d+) . Chúng ta có thể sử dụng logic tương tự để trích xuất mất xác thực bằng Valid loss: (\d+\.\d+) .

Đây là một cách để trích xuất thông tin này bằng Python:

import re
f = open("log_train.txt", "r").read()
train_loss = re.findall(r'Train loss: (\d+\.\d+)', f)
valid_loss = re.findall(r'Valid loss: (\d+\.\d+)', f)
train_loss = [float(i) for i in train_loss]
valid_loss = [float(i) for i in valid_loss]
print("train_loss =", train_loss)
print("")
print("valid_loss =", valid_loss)

Khi có một nhóm chụp, re.findall tìm kiếm tất cả các dòng và trả về các giá trị bên trong nhóm chụp trong danh sách.

Bất kỳ hàm biểu thức chính quy nào cũng chỉ trả về chuỗi, do đó các giá trị được chuyển đổi thành số float và được in ra. Sau đó, bạn có thể trực tiếp sử dụng chúng trong tập lệnh Python khác dưới dạng danh sách các số float.

Đây là kết quả:

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bạn cũng có thể sử dụng sed, lưu kết quả đầu ra trong train_losses.txt và đọc từ tệp. Trước tiên, chúng tôi sử dụng '/Train/' để chỉ nhắm mục tiêu các dòng có 'Train', sau đó chúng tôi sẽ áp dụng biểu thức chính quy tương tự như trước đây.

sed -En '/Train/ s/.*Train loss: ([0-9]+\.[0-9]+).*/\1/p' log_train.txt | tee train_losses.txt

".*" được thêm vào đầu và cuối để sed khớp với nội dung của tất cả các dòng có liên quan. Sau đó toàn bộ dòng được thay thế bằng giá trị của nhóm chụp. tee lệnh được sử dụng để chuyển hướng đầu ra của sed thành train_losses.txt đồng thời in nội dung trong terminal.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Hãy dành chút thời gian để suy nghĩ xem bạn cần những gì để trích xuất các kỷ nguyên. Bạn phải trích xuất 500 từ [500/10000] cho tất cả các dòng như vậy. Mảng sẽ có dạng [1, 500, 1000, 1500, ...]. Bạn có thể làm theo cách tiếp cận tương tự như chúng tôi đã sử dụng cho ví dụ trước.

Lưu ý rằng nếu bạn muốn khớp "[ " hoặc "] ", bạn phải thoát khỏi nó. Câu trả lời được đưa ra ở đây.

Đổi tên tệp hàng loạt

Bạn có các tệp này với một số giá trị ngẫu nhiên làm tiền tố. Bạn phải đổi tên tất cả các tệp thành 1.mp4, 2.mp4, v.v.. Đây là cách các tệp được tạo.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Đây là trường hợp phổ biến khi bạn có danh sách các tệp có số thứ tự trong tên nhưng cũng có một số ký tự khác mà bạn không muốn.

Mẫu phải khớp bất kỳ thứ gì với Tập, sau đó là dấu gạch dưới, sau đó là số và .mp4 ở cuối.

Giá trị liên quan là số trước '.mp4' mà chúng tôi sẽ đặt trong nhóm chụp. .*Episode_ sẽ khớp mọi thứ với số lượng. Sau đó chúng ta có thể nắm bắt được số đó bằng ([0-9]+) và cũng khớp .mp4 với \.mp4 .

Vậy biểu thức chính quy cuối cùng là .*Episode_([0-9]+)\.mp4 . Vì chúng tôi muốn giữ .mp4 chuỗi thay thế sẽ là \1.mp4 .

Đây là một cách để giải quyết bằng sed.

for i in *.mp4; do
 newname=$(echo $i | sed -En 's/.*Episode_([0-9]+)\.mp4/\1.mp4/p')
 mv $i $newname
done;ls

Đầu tiên, tên mới được lưu trong một biến và sau đó lệnh mv được sử dụng để đổi tên tệp.

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Có phải chúng ta vừa sử dụng .* thay cho .*Episode_ ? Trong ví dụ này thì có. Nhưng có thể có tên tệp như Steins_Gate0.mp4 trong đó 0 là một phần của tên phim và bạn không thực sự muốn đổi tên tệp này nên tốt hơn hết là bạn nên đặt tên càng cụ thể càng tốt.

Điều gì sẽ xảy ra nếu một số tệp được đặt tên là "Random_Episode6.mp4"? Sự khác biệt là không có dấu gạch dưới sau Tập. Bạn cần thực hiện thay đổi gì?

Câu trả lời là bạn sẽ cần thêm dấu "?" sau "_" để làm tùy chọn. Regex sẽ là .*Episode_?([0-9]+)\.mp4 .

Xác thực email

Có đủ loại biểu thức chính quy phức tạp để xác thực email.

Đây là một cách đơn giản:^[^@ ]+@[^@.]+\.\w+$ . Nó phù hợp với định dạng A@B.C

Bảng bên dưới chia mẫu này thành các phần nhỏ hơn:

Mẫu phù hợp ^ đầu dòng[^@ ]+ bất cứ điều gì ngoại trừ "@" và ký tự khoảng trắng@[^@.]+ @ theo sau là bất cứ thứ gì ngoại trừ "@" và "." ký tự\.\w+ "." theo sau là các ký tự từ$ cuối dòng

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Trong trang web regrec, bạn có thể bật cờ nhiều dòng từ tab Cờ ở góc trên bên phải. 'gm' ở cuối cho biết cờ nhiều dòng đã được bật.

Chúng ta có thể thấy dòng 2,3,5,6 không khớp. Bạn có thể tìm ra lý do và phần nào của biểu thức chính quy chịu trách nhiệm loại bỏ nó không?

Câu trả lời được đưa ra ở đây

Hạn chế mật khẩu

Bạn cũng có thể sử dụng biểu thức chính quy để áp đặt các ràng buộc. Ở đây chúng ta sẽ khám phá sức mạnh của cái nhìn tích cực.

Giả sử chúng ta chỉ muốn chấp nhận một chuỗi nếu có một chữ số trong đó. Bạn đã biết cách tìm một chữ số với lớp '\d'. Để thực hiện được điều đó, chúng ta có thể sử dụng [^\d]*\d . Điều này sẽ khớp với bất kỳ ký tự không có chữ số nào từ 0 lần trở lên và sau đó khớp với một chữ số.

Chúng ta cũng có thể sử dụng biểu thức .*\d để khớp với một chữ số. Vì vậy, nếu không có chữ số nào trong chuỗi thì việc xem trước sẽ thất bại và không có ký tự nào của chuỗi đó khớp với nhau, trả về một chuỗi trống "".

Khi sử dụng ngôn ngữ lập trình, chúng ta có thể kiểm tra xem biểu thức chính quy có trả về một chuỗi trống hay không và xác định rằng các ràng buộc không được thỏa mãn.

Chúng tôi sẽ tạo một biểu thức chính quy áp đặt các tiêu chí sau:

  1. Tối thiểu 8 ký tự và tối đa 16 ký tự.
  2. Ít nhất một chữ cái viết thường.
  3. Ít nhất một chữ cái viết hoa.
  4. Ít nhất một số.

Để đạt được điều này, bạn có thể sử dụng những cái nhìn tích cực. Đây là biểu thức chính quy:

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,16}$

Bảng bên dưới giải thích phần nào của biểu thức chính quy áp đặt ràng buộc nào:

Ràng buộc mẫu .{8,16} tối thiểu 8 và tối đa 16 ký tự(?=.*[a-z]) tối thiểu một chữ cái viết thường(?=.*[A-Z]) tối thiểu một chữ hoa(?=.*\d) tối thiểu một chữ số

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bạn cần sửa đổi gì để áp đặt ít nhất 5 chữ cái viết hoa?

Bạn có thể nghĩ (?=.*[A-Z]{5,}) sẽ thực hiện công việc. Nhưng biểu thức này yêu cầu tất cả 5 chữ cái phải ở cùng nhau. Một chuỗi như rand-ABCDE-rand sẽ được khớp nhưng 0AxBCDxE0 sẽ không khớp ngay cả khi nó có 5 chữ in hoa (vì chúng không liền kề nhau).

Một lần nữa, chúng tôi có các nhóm bắt giữ đến giải cứu. Chúng tôi muốn khớp 5 chữ cái viết hoa ở bất kỳ đâu trong chuỗi. Chúng ta đã biết rằng chúng ta có thể khớp 1 chữ cái viết hoa với .*[A-Z] . Bây giờ chúng ta sẽ đặt chúng vào trong một nhóm chụp và đính kèm bộ định lượng tối thiểu là 5. Biểu thức sẽ là (.*[A-Z]){5,} .

Đây là câu trả lời cuối cùng:

Thay cho (?=.*[A-Z]) bạn sẽ cần (?=(.*[A-Z]){5,}) . Biểu thức trở thành ^(?=.*[a-z])(?=(.*[A-Z]){5,})(?=.*\d).{8,16}$ .

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Bạn cũng có thể yêu cầu mật khẩu không chứa một số từ nhất định để thực thi mật khẩu mạnh hơn.

Ví dụ:chúng tôi muốn từ chối mật khẩu nếu chứa pass hoặc 1234 . Cái nhìn tiêu cực là công cụ cho công việc này. Regex sẽ là ^(?!.*(pass|1234)).*$ .

Nắm vững biểu thức chính quy:Hướng dẫn thực hành với các ví dụ thực tế

Trong biểu thức chính quy này, chúng tôi đặt pass1234 bên trong một nhóm chụp và sử dụng toán tử OR logic. Nhóm chụp này được lồng bên trong một nhóm chụp khác có tiền tố là ?!.* . Điều này làm cho nó trở thành một cái nhìn tiêu cực phù hợp nếu có ít nhất 8 ký tự trước .{8,} với điều kiện là pass hoặc 1234 không thể có mặt ở bất cứ đâu trong chuỗi.

Lời cuối cùng

Tôi hy vọng bạn đã thực hành tốt khi xem qua bài viết này. Không sao nếu bạn quên một số cú pháp. Điều quan trọng là hiểu các khái niệm cốt lõi và có ý tưởng hay về những gì có thể làm được với biểu thức chính quy. Sau đó, nếu bạn quên một mẫu, bạn có thể tìm trên Google hoặc tham khảo một mẫu.

Bạn càng thực hành nhiều, bạn sẽ càng thành công hơn mà không cần sự trợ giúp từ bên ngoài. Cuối cùng, bạn sẽ có thể viết các biểu thức chính quy siêu phức tạp và hiệu quả hoàn toàn ngoại tuyến.

Hiện đã có một số bảng tính biểu thức chính quy hay, vì vậy tôi muốn tạo ra thứ gì đó chuyên sâu hơn ở đây để bạn có thể tham khảo về các khái niệm cốt lõi và các trường hợp sử dụng phổ biến.

Nếu bạn đang tìm kiếm một cheatsheet, thì cái từ QuickRef sẽ hữu ích. Đây là nơi tốt để nhớ lại cú pháp và chúng cũng cung cấp một số thông tin tổng quan cơ bản về các hàm liên quan đến biểu thức chính quy trong nhiều ngôn ngữ lập trình khác nhau.

Hầu hết các kỹ thuật biểu thức chính quy đều giống nhau ở tất cả các ngôn ngữ và công cụ lập trình – nhưng một số công cụ nhất định có thể cung cấp các tính năng bổ sung. Vì vậy, hãy thực hiện một số nghiên cứu về công cụ bạn đang sử dụng để chọn công cụ tốt nhất cho mình.

Đề xuất cuối cùng của tôi là không nên ép buộc sử dụng biểu thức chính quy chỉ vì bạn có thể. Rất nhiều khi string.find() thông thường là đủ để hoàn thành công việc. Nhưng nếu bạn sống ở nhà ga, chắc chắn bạn thực sự có thể làm được nhiều việc chỉ với biểu thức chính quy.

Nếu bạn thích loại bài viết này, bạn có thể theo dõi blog hoặc twitter của tôi.

Học cách viết mã miễn phí. Chương trình giảng dạy mã nguồn mở của freeCodeCamp đã giúp hơn 40.000 người có được việc làm với tư cách là nhà phát triển. Bắt đầu