Sử dụng regex trong ruby

Sử dụng Regex trong ruby

I. RegEx

Regex là viết tắt của Regular Expression, là một chuỗi miêu tả một tập hợp các chuỗi khác, theo những quy tắc và cú pháp nhất định. Regex thường được sử dụng với các tiện ích tìm kiếm, xử lý văn bả dựa trên các mẫu được quy định. Rất nhiều ngôn ngữ hỗ trợ biểu thức chính quy (Regex) khi xử lý chuỗi như Perl, Javascript, Ruby .... và một số khác thông qua thư viện chuẩn như ngôn ngữ Java, Python, C++, .NET. Hầu hết các ngôn ngữ đều cung cấp Regex thông qua các thư viện.

Regex được sử dụng để kiểm tra sự hợp lệ của dữ liệu đầu vào là các string, như kiểm tra địa chỉ url, username, password, phone number, email ... Kết quả trả về của Regex có thể hiểu một cách đơn giản là kết quả của sự so sánh khớp nhau giữa biểu thức. Các bạn có thể viết Regex và thử các trường hợp với trang web http://rubular.com/

Ưu điểm :

  • Linh hoạt, sử dụng tốt với nhiều ngôn ngữ.
  • Xử lý các chuỗi một cách ngắn gọn và tiện lợi.
  • Giảm thiểu thời gian và công sức khi lập trình. Vì chỉ cần viết một biểu thức mẫu là có thể đảm bảo được dữ liệu đầu vào.

Nhược điểm :

  • Dễ sai, dễ tiềm ẩn lỗi.
  • Khó học vì phải nắm bắt tốt các quy tắc cũng như có tư duy logic tốt.

II. Ý nghĩa của các kí tự trong regular

  • ^: Bắt đầu string, phù hợp với những chuỗi string bắt đầu bằng ký tự đặt sau dấu ^. Nếu có nhiều dòng trong chuỗi string thì cũng phù hợp sau khi một character xuống dòng. Ví dụ, /^A/ không phù hợp với ký tự A trong "an A", nhưng phù hợp với ký tự 'A' trong "An E". Ký tự '^' có ý nghĩa khác nhau khi nó xuất hiện như là ký tự đầu tiên trong một ký tự pattern.
  • $: Kết thúc string, phù hợp với những chuỗi string kết thúc bằng ký tự đặt sau dấu . Nếu có nhiều dòng trong chuỗi string thì cũng phù hợp trước khi một character xuống dòng. Ví dụ, /t/ không phù hợp với ký tự 't' trong chuỗi "eater", nhưng phù hợp trong chuỗi "eat"
  • a*: Xuất hiện kí tự a 0 hoặc nhiều l. Tương đương với {0, }
  • Ví dụ , /to*/ phù hợp với 'too' trong chuỗi "It's too long" và 't' trong chuỗi “thanks you" nhưng không phù hợp trong chuỗi "ask him".
  • a+: Xuất hiện kí tự a ít nhất một lần trong chuỗi string. Tương tự với {1, }
  • Ví dụ, /d+/ phù hợp với ký tự a trong chuỗi "done" và tất cả ký tự a trong chuỗi, nhưng không có trong chuỗi "alone"
  • a?: Có hoặc không có kí tự a.
  • Ví dụ /https?/ phù hợp với 'https' nhưng cũng phù hợp với 'http'
  • .(dấu chấm thập phân): phù hợp với bất kỳ một ký tự nào ngoại trừ ký tự xuống dòng Ví dụ, /.d/ phù hợp với 'od' trong chuỗi "have a good day" nhưng không phù hợp với 'moon day'
  • x|y : Hoặc có x hoặc y hoặc có cả 2 Ví dụ /love | like/ phù hợp với 'like' trong "I like fish" và 'love' trong "I love her"
  • a{n} : Kí tự a xuẩt hiện n lần trong chuỗi, n phải là số nguyên dương Ví dụ, /o{2}/ không phù hợp với 'o' trong "alone", nhưng lại phù hợp với tất cả các 'o' trong "good man" .
  • a{n, m} : n <= m và n,m phải là số nguyên dương. Kí tự a xuất hiện tối thiểu n lần và tối đa m lần trong chuỗi ký tự. Khi không điền giá trị của m, thì m được xem là có giá trị ∞ Ví dụ, /g{1, 3}/ không phù hợp trong "test", nhưng lại phù hợp với 1 ký tự 'g' trong "good test", 2 ký tự 'g' trong "ggood" và 3 ký tự đầu tiên trong "gggreen"
  • \d : Các ký tự số [0-9] Ví dụ, /\d/ hoặc /[0-9]/ phù hợp với '1' trong "1 book"
  • \D: Các ký tự không phải số [^0-9] Ví dụ, /\D/ hoặc /[^0-9]/ phù hợp với 'good string'
  • \s: Khoảng trắng. Nó sẽ khớp với tất các các chuỗi chứa khoảng trắng như “white house” và sẽ không khớp với các chuỗi như “aaagoodman”
  • \S: Tất cả các chữ ko phải là khoảng trắng. Sẽ khớp với tất cả các chuỗi không chưa khoảng trắng như "http://domain.com" và không khớp với bất kì chuỗi nào chứa khoảng trắng như "http://do main.com"

III. Một vài tips cho Regex với Ruby

1. Sử dụng %r{}

%r{} tương đương với /.../, nhưng nó cho phép bạn có thể viết '/' ở bên trong regex. \Ahttps?😕/\S+.\S+\s*\z %r{\Ahttps?😕/\S+.\S+\s*\z}

2. Tìm vị trí khớp

2.1.5 :001 > s = "test and check" => "test and check" 2.1.5 :002 > idx = s =~ /check/ => 9 2.1.5 :003 > idx => 9

Như vậy s =~ /check/ sẽ trả về : Vị trí đầu tiên trong chuỗi s khớp với pattern /check/. Nếu không khớp thì kết quả là nil

3. Kiểm tra xem có khớp không

s = "test and check" if s =~ /check/ puts "condition satisfied" else puts "not satisfied" end

4. Sử dụng với gsub

Bạn nên sử dụng gsub với regex và nhiều trường hợp bạn bắt buộc phải sử dụng regex vì nó sẽ bắt được trường hợp bạn cần. 2.1.5 :050 > " test with gsub".gsub(/gsub/, "okok") => " test with okok" 2.1.5 :051 > " test with gsub".gsub(/\s/, "") => "__test_with__gsub" 2.1.5 :053 > " test with gsub".gsub(%r{,\s*}, "") => " test with gsub" 2.1.5 :054 > " test with gsub".gsub(%r{\sgsub}, "okok") => " test with okok"

5. Sử dụng chung với split

Sử dụng split với regex sẽ mang lại nhiều lợi ích cho bạn, bởi vì regex sẽ bắt được trường hợp đa dạng hơn so với mặc định của split. 2.1.5 :020 > " now's the time".split => ["now's", "the", "time"] 2.1.5 :021 > " now's the time".split(' ') => ["now's", "the", "time"] 2.1.5 :022 > " now's the time".split(/ /) => ["", "now's", "", "the", "time"] 2.1.5 :023 > "1, 2.34,56, 7".split(%r{,\s*}) => ["1", "2.34", "56", "7"] 2.1.5 :024 > "hello".split(//) => ["h", "e", "l", "l", "o"] 2.1.5 :025 > "hello".split(//, 3) => ["h", "e", "llo"] 2.1.5 :026 > "hi mom".split(%r{\s*}) => ["h", "i", "m", "o", "m"]

6. Trích

Để trích ra ta dùng dấu ngoặc. Nếu khớp, phần dấu ngoặc đầu tiên sẽ được trích ra thành biếtn $1, tương tự với $2 và $3 2.1.5 :001 > s = "regex is good" => "regex is good" 2.1.5 :002 > s =~ /(.+) (.+?) (.+)/ => 0 2.1.5 :003 > $1 => "regex" 2.1.5 :004 > $2 => "is" 2.1.5 :005 > $3 => "good"


All Rights Reserved