Regex trong java

Bài regex đã nói về cách tạo ra các đoạn regex đấy như thế nào, bài này mình sẽ nói về việc sử dụng regex trong java như thế nào.

Mục tiêu của regex vẫn là search, extract value và replace.

Trong Java có 2 class chính làm việc với regex:

  • Pattern: Nơi lưu trữ regex
  • Matcher: Engine nơi thực hiện việc match và trả lại kết quả sau khi match.

Ví dụ 1: Simple case

@Test
void name3() {
    Pattern pattern = Pattern.compile("\\d{3}");
    String input = "nguyen van A 4445, 6667";
    Matcher matcher = pattern.matcher(input);
    while (matcher.find()) {
        System.out.printf("from %d to %d with text=%s", matcher.start(), matcher.end(),
                input.substring(matcher.start(), matcher.end()));
        System.out.println();
    }
}

Kết quả sẽ là:

from 13 to 16 with text=444
from 19 to 22 with text=666

Giải thích 1 chút:

  • Để tạo được Pattern object, phải dùng static method .compile(String regex) hoặc .compile(String regex, int flags)
  • Sau đó, sẽ gọi method .matcher(String input) –> tạo ra Matcher object.
  • Từ Matcher object sẽ gọi method .matcher.find() –> kiểm tra xem có match hay ko? Nếu match nhiều hơn 1 lần, thì sẽ gọi tiếp .matcher.find(). Đó là lý do ở đây dùng while() vì không biết sẽ match bao nhiêu lần.

Lưu ý: Trong Java, dấu \ là escape character, do đó, \d hay \w muốn giữ nguyên được ý nghĩa thì phải là \\d hay \\w

Ví dụ 2: Greedy strategy – xóa bỏ nhiều ký tự

Mình có input String như sau:

amlbcookie=01;Path=/;Domain=mydomain.com;Secure;HttpOnly tvgauthcookie=C6nl2pVadONSclRAaL1gxWd2-60.AAJTSQACMDYAAlNLABxFOTFSWk1nUW9Td1NJOHhrSHppUW1FUHdKdG89AAR0eXBlAANDVFMAAlMxAAIwMQ..;Path=/;Domain=mydomain.com;Secure;HttpOnly BIGipServerqavgamws-https-pool=1234567890.12345.0000;Path=/;Secure;HttpOnly

Bây giờ mình muốn xóa những ký tự từ chỗ BIGipServer... cho đến hết.

@Test
void name4() {
    String cookies = "amlbcookie=01;Path=/;Domain=mydomain.com;Secure;HttpOnly tvgauthcookie=C6nl2pVadONSclRAaL1gxWd2-60.AAJTSQACMDYAAlNLABxFOTFSWk1nUW9Td1NJOHhrSHppUW1FUHdKdG89AAR0eXBlAANDVFMAAlMxAAIwMQ..;Path=/;Domain=mydomain.com;Secure;HttpOnly BIGipServerqavgamws-https-pool=1234567890.12345.0000;Path=/;Secure;HttpOnly";
    String sub = cookies.replaceAll(" BIG(.+)", "");
    System.out.println(sub);
}

Sử dụng method .replaceAll(String regex, String replacement) của String để find and replace.

  • Đoạn regex là BIG(.+) vì mình biết đoạn muốn cắt là bắt đầu từ chữ BIG và mình muốn nó match nhiều nhất có thể, cho đến hết luôn –> dùng Greedy strategy là (.+) để match mọi thứ còn lại

Ví dụ 3: Tách lấy 1 giá trị trong 1 đoạn String

Input String như sau

{967bd6fe-9759-44aa-95ed-821c690f98f2={provider_recipient_uuid=972e84de-e099-444f-b854-c83b1aac47d9, payment_type=regular, is_swift_recipient=false, service=fx, can_transfer=true}, 967bd718-bf3e-4b14-9110-61b67e0f592a={provider_recipient_uuid=null, payment_type=null, is_swift_recipient=null, service=mca, can_transfer=true}}

Mình chỉ muốn lấy cái value của key provider_recipient_uuid đầu tiên.

@Test
void name5() {
    String input = "{967bd6fe-9759-44aa-95ed-821c690f98f2={provider_recipient_uuid=972e84de-e099-444f-b854-c83b1aac47d9, payment_type=regular, is_swift_recipient=false, service=fx, can_transfer=true}, 967bd718-bf3e-4b14-9110-61b67e0f592a={provider_recipient_uuid=null, payment_type=null, is_swift_recipient=null, service=mca, can_transfer=true}}";

    Pattern pattern = Pattern.compile("provider_recipient_uuid=(.+?),");
    Matcher matcher = pattern.matcher(input);
    String provider_recipient_uuid = "";
    if (matcher.find()) {
        provider_recipient_uuid = matcher.group(1);
    }
    System.out.println(provider_recipient_uuid);
    //972e84de-e099-444f-b854-c83b1aac47d9
}
  • Đầu tiên, nhận thấy value đó nằm giữa provider_recipient_uuid=, mình tạo 1 group (.+?) để match đoạn nằm ở giữa đó. Nếu chỗ này, mình dùng Greedy strategy thay cho Reluctant strategy thì nó sẽ match từ cái provider_recipient_uuid= đầu tiên đến cái dấu phảy , cuối cùng luôn.
  • Tuy nhiên, sẽ có 2 vị trí match được trong này, đó là:
    • provider_recipient_uuid=972e84de-e099-444f-b854-c83b1aac47d9,
    • provider_recipient_uuid=null,
  • Do đó, thay vì dùng while() để lấy nhiều nhất có thể, mình chỉ dùng if() để check kết quả đầu tiên match được.
  • matcher.group() có 2 overloaded methods chính:
    • group() sẽ trả lại group(0) –> chính là toàn bộ cái match đó, ví dụ provider_recipient_uuid=972e84de-e099-444f-b854-c83b1aac47d9,
    • group(int group) sẽ trả lại value của theo thứ tự của group, ở đây mình chỉ có 1 group trong câu regex, mình sẽ dùng group(1), nó chính là cái (.+?) trong TH này: 972e84de-e099-444f-b854-c83b1aac47d9


5 2 votes
Article Rating
Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Annh
Annh
2 years ago

This is not normal. I think you’re great.