12/08/2018, 14:57

Exploring some string methods

Trong thực tế khi phát triển ứng dụng, việc sử lý với string là một điều thường xuyên diễn ra. Trong bài viết này sẽ giới thiệu vài ví dụ khi xử lý string trong Ruby Ví dụ bạn đang phát triển một API, nó yêu cầu số điện thoại theo một định dạng như 555-555-5555. Bạn muốn người dùng nhập vào theo ...

Trong thực tế khi phát triển ứng dụng, việc sử lý với string là một điều thường xuyên diễn ra. Trong bài viết này sẽ giới thiệu vài ví dụ khi xử lý string trong Ruby Ví dụ bạn đang phát triển một API, nó yêu cầu số điện thoại theo một định dạng như 555-555-5555. Bạn muốn người dùng nhập vào theo đúng định dạng này, nhưng người dùng không phải luôn luôn nhập đúng, ngay cả khi bạn hiển thị placeholder với ví dụ một số điện thoại đúng format. Hay đôi khi trong phát triển ứng dụng chúng ta cũng gặp một số trường hợp phải xử lý những chuỗi string theo đúng định dạng như vậy. Để làm điều đó đơn giản nhất, chúng ta có thể chuyển đổi bất cứ thứ gì mà người dùng nhập vào thành đúng định dạng mong muốn, giả định là những gì người dùng nhập vào đều có thể chuyển đổi. Ví dụ như:

  • 1112223333
  • (555) 123-1234
  • 123 123 1234
  • 1-123-123-1234
  • 111.222.3333 Nếu người dùng nhập vào một số ký tự mà chúng ta không thể chuyển đổi đúng định dạng, chúng ta có thể bỏ qua nó và đưa ra một xác nhận lỗi từ người dùng (ví dụ như 123-123-1234 x123, 123fffa, nothing..)

Yêu cầu xử lý

Chúng ta xử lý theo một chuỗi biến đổi sau

  1. Xóa đi những ký tự không phải số (0 - 9), thay thể chúng bằng ký tự rỗng
  2. Nếu có 11 ký tự và bắt đầu bằng số 1, chúng ta thay số đầu tiên bằng dấu trừ (-)
  3. Nếu có 10 ký tự, chèn vào sau ký tự thứ 3 và thứ 6 dấu (-)

Code xử lý

Dưới đây là đoạn code xử lý chuyển đổi số điện thoại về đúng định dạng hợp lệ mong muốn

class NormalizePhone
  def self.normalize(phone)
    # Replace any non-numbers with ""
    temp = phone.to_s.gsub(/[^0-9]*/, "")

    # If 11 digits long and first digit is 1, remove it
    if temp.size == 11 && temp.start_with?("1")
      temp = temp[1..(temp.size - 1)]
    end

    # Re-insert dashes if 10 digits long
    if temp.size == 10
      phone = temp.insert(3, "-").insert(7, "-")
    end

    phone
  end
end

Tìm hiểu về các method sử dụng

Chúng ta hãy xem qua các String phương thức khác nhau mà chúng ta đã sử dụng trên.

Gsub

gsub là một phương thức rất tuyệt vời trong việc tìm kiếm ký tự hay chuỗi theo mẫu (regular expression) và thay thế tất cả chúng bằng đoạn string mà bạn muốn. Phương thức này khác với sub - phương thức mà chỉ thay thế thực thể (ký tự hoặc tring) đầu tiên tìm kiếm ra.

"(555) 123-1234".gsub(/[^0-9]*/, "") # 5551231234

Start with?

Tiếp theo chúng ta sử dụng start_with? phương thức để xem xem số điện thoại có bắt đầu bởi số 1 hay không. Nếu trả về true và số điện thoại có độ dài 11 số thì chúng ta sẽ thay thế số đầu tiên bằng dấu (-)

"11231231234".start_with?("1") # true

Slice

Để bỏ đi số "1" bắt đầu của string, chúng ta dùng phương thức slice. Điều này giống với substring trong ngôn ngữ khác nhưng nó lại có sức mạnh hơn khi người dùng có thể truyền vào nhiều những tùy chọn xử lý. Trong ví dụ này chúng ta sẽ truyền vào giá trị đầu tiên và độ dài

temp = "11231231234"
temp.slice(1, temp.length - 1) # "1231231234"

Insert

Đến đây, giả sử số điện thoại gồm 10 số và chỉ bao gồm các ký tự hợp lý, chúng ta sẽ chèn vào các ký tự (-) sau ký tự thứ 3 và sau ký tự thứ 6. Để làm điều này chúng ta sẽ sử dụng phương thức insert

"1112223333".insert(3, "-").insert(7, "-") # "111-222-3333"

Test

Dưới đây là các test case để đảm bảo các phương thức được viết đúng

describe NormalizePhone do

  it "123-123-1234 stays valid" do
    expect(NormalizePhone.normalize("123-123-1234")).to eq("123-123-1234")
  end

  it "1231231234 converts correctly" do
    expect(NormalizePhone.normalize("1231231234")).to eq("123-123-1234")
  end

  it "(123) 123-1234 converts correctly" do
    expect(NormalizePhone.normalize("(123) 123-1234")).to eq("123-123-1234")
  end

  it "123.123.1234 converts correctly" do
    expect(NormalizePhone.normalize("123.123.1234")).to eq("123-123-1234")
  end

  it "nothing remains as is" do
    expect(NormalizePhone.normalize("nothing")).to eq("nothing")
  end

  it "1231231234567 remains as is" do
    expect(NormalizePhone.normalize("1231231234567")).to eq("1231231234567")
  end

  it "123-123-1234 x123 remains as is" do
    expect(NormalizePhone.normalize("123-123-1234 x123")).to eq("123-123-1234 x123")
  end

end

Và ouput test

.......

Finished in 0.00266 seconds (files took 0.48769 seconds to load)
7 examples, 0 failures

References

Exploring some string methods

0