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.
Nội dung bài viết
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ùngwhile()
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=
và,
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áiprovider_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ùngif()
để check kết quả đầu tiên match được. matcher.group()
có 2 overloaded methods chính:group()
sẽ trả lạigroup(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ùnggroup(1)
, nó chính là cái(.+?)
trong TH này:972e84de-e099-444f-b854-c83b1aac47d9
This is not normal. I think you’re great.
Thanks! 🙂