Biểu thức chính quy trong java [Regular Expression] – https://final-blade.com

[Java] – Biểu thức chính quy hay nói cách khác regular expressions là những mẫu (pattern) dùng để mô tả một lớp ký tự nào đó theo những quy tắc và cú pháp nhất định mà các nhà phát triển xây dựng tạo ra.

1.Các ngôn ngữ được hỗ trợ biểu thức chính quy

Biểu thức chính quy được hỗ trợ hầu như tất cả các ngôn ngữ như : Java, C#, C/C++,Javascript,Python…v..v

Đa số các ngôn ngữ lập trình hiện nay đều hỗ trợ biểu thức chính quy

 

2.Ưu và nhược điểm của biểu thức chính quy

2.1- Điểm mạnh

Điểm mạnh của biểu thức chính quy giúp tất cả chúng ta hoàn toàn có thể kiểm tra, bắt lỗi và giải quyết và xử lý những tiện ích tìm kiếm những chuỗi từ người dùng nhập vào dựa trên những mẫu lao lý sẵn. Ví dụ để kiểm tra email nhập có đúng chuẩn hay không thì những bạn hoàn toàn có thể sử dụng biểu thức chính quy để kiểm tra email trong java ví dụ điển hình, hay một ví dụ khác rằng để kiểm tra người dùng có nhập những ký tự đặc biệt quan trọng vào form hay không ? Lúc này những bạn sử dụng biểu thức chính quy để kiểm tra hay bắt lỗi đó …

2.2- Điểm yếu

Biểu thức chính quy ( regular expressions ) được tương hỗ bởi hầu hết những ngôn từ lập trình lúc bấy giờ trên thếgiới, tuy nhiên điểm hạn chế là mỗi ngôn từ lại được tương hỗ biểu thức một cách khác nhau. Ví nguyên do này nên bắt đầu những lập trình viên học và khám phá khá khó, nhưng hiệu suất cao nếu được sử dụng, vận dụng tốt .
Trong Java thì biểu thức chính quy có 1 số ít quy tắc và cách lao lý viết riêng, tất cả chúng ta cùng đi tìm hiểu và khám phá cụ thể hơn cũng như 1 số ít những biểu thức chính quy để kiểm tra thường được sử dụng thì mình sẽ liệt kê ra ở phần cuối bài viết này .

Biểu thức chính quy trong java [Regular Expression]

3.Các quy tắc viết biểu thức chính quy trong java

Dưới đây là bảng những quy tắc để viết biểu thức chính quy – Regular Expression trong java :

TT Biểu thức chính quy Mô tả
1 . Khớp (match) với bất kỳ ký tự nào
2 ^regex Biểu thức chính quy phải  khớp tại điểm bắt đầu
3 regex$ Biểu thức chính quy phải khớp ở cuối dòng.
4 [abc] Thiết lập định nghĩa, có thể khớp với a hoặc b hoặc c.
5 [abc][vz] Thiết lập định nghĩa, có thể khớp với a hoặc b hoặc c theo sau là v hay z.
6 [^abc] Khi dấu ^ xuất hiện như là nhân vật đầu tiên trong dấu ngoặc vuông, nó phủ nhận mô hình. Điều này có thể khớp với bất kỳ ký tự nào ngoại trừ a hoặc b hoặc c.
7 [a-d1-7] Phạm vi: phù hợp với một chuỗi giữa a và điểm d và con số từ 1 đến 7.
8 X|Z Tìm X hoặc Z.
9 XZ Tìm X và theo sau là Z.
10 $ Kiểm tra kết thúc dòng.
11 \d Số bất kỳ, viết ngắn gọn cho [0-9]
12 \D Ký tự không phải là số, viết ngắn gon cho [^0-9]
13 \s Ký tự khoảng trắng, viết ngắn gọn cho [ \t\n\x0b\r\f]
14 \S Ký tự không phải khoản trắng, viết ngắn gọn cho [^\s]
15 \w Ký tự chữ, viết ngắn gọn cho [a-zA-Z_0-9]
16 \W Ký tự không phải chữ, viết ngắn gọn cho [^\w]
17 \S+ Một số ký tự không phải khoảng trắng (Một hoặc nhiều)
18 \b Ký tự thuộc a-z hoặc A-Z hoặc 0-9 hoặc _, viết ngắn gọn cho [a-zA-Z0-9_].
19 * Xuất hiện 0 hoặc nhiều lần, viết ngắn gọn cho {0,}
20 + Xuất hiện 1 hoặc nhiều lần, viết ngắn gọn cho {1,}
21 ? Xuất hiện 0 hoặc 1 lần, ? viết ngắn gọn cho {0,1}.
22 {X} Xuất hiện X lần, {}
23 {X,Y} Xuất hiện trong khoảng X tới Y lần.
24 *? * có nghĩa là xuất hiện 0 hoặc nhiều lần, thêm ? phía sau nghĩa là tìm kiếm khớp nhỏ nhất.

4.Sử dụng String.matches(String)

4.1 – Định nghĩa

String.matches(String) được dùng để kiểm tra chuỗi từ người dùng có phù hợp với biểu thức do chúng ta viết với regex hay không.

4.2 – Ví dụ

Trong ví dụ về String. matches ( String ), tất cả chúng ta lấy 2 ví dụ đơn cử như sau :
1 ) Kiểm tra nếu chuỗi có chứa bất kể những ký tự hay không ? Trong cả hai ví dụ chuỗi từ A-Z hoặc a-Z .
2 ) Kiểm tra nếu chuỗi có chứa bất kể một chữ số. Ví dụ như ký tự số 1-9 hoặc 0-9 …
Các bạn theo dõi ví dụ dưới đây :

package regex;

public class StringMatchExample {
	public static void main(String args[]) {
		// kiểm tra xem chuỗi có chứa các chuỗi các ký tự từ A-Z a-Z hay không
		String[] alphabets = { "", "12345", "A12345", "12345B", "12345a",
				"abcd", "aa343" };

		for (String alphabet : alphabets) {
			System.out.println(" Chuỗi " + alphabet
					+ " có chứa các chữ cái : "
					+ alphabet.matches(".*[A-Za-z].*"));

		}

		// kiểm tra xem chuỗi có chứa các chữ số hay không
		String[] numbers = { "1234", "+1234", "234a" };
		for (String number : numbers) {
			System.out.println(" Chuỗi  " + number
					+ " chứa các số từ 1-9  : "
					+ number.matches(".*[1-9].*"));
		}

	}
}

Kết quả như sau :

 

 Chuỗi  có chứa các chữ cái : false
 Chuỗi 12345 có chứa các chữ cái : false
 Chuỗi A12345 có chứa các chữ cái : true
 Chuỗi 12345B có chứa các chữ cái : true
 Chuỗi 12345a có chứa các chữ cái : true
 Chuỗi abcd có chứa các chữ cái : true
 Chuỗi aa343 có chứa các chữ cái : true
 Chuỗi  1234 chứa các số từ 1-9  : true
 Chuỗi  +1234 chứa các số từ 1-9  : true
 Chuỗi  234a chứa các số từ 1-9  : true


Như vậy,với String.matches(String) trong java,nếu kiểm tra đúng sẽ trả về bằng true,sai tất nhiên bằng giá trị false.

package regex;

public class StringMatchExample2 {
	public static void main(String args[]) {
			String str1 = "i";
		    System.out.println("Chuỗi thứ nhất là " + str1);
		    // kiểm tra chuỗi str1 có bắt đầu bằng ký tự i
		    //== true
		    boolean resultStr1 = str1.matches("^i");
		    System.out.println("-Match ^i : " + resultStr1);
		    
		    String str2= "it phu tran";
		    System.out.println("Chuỗi thứ hai là " + str2);
		    // kiểm tra chuỗi str2 có bắt đầu bằng ký tự i,vậy trong trường hợp này,bạn đọc
		    // thấy rằng chuỗi it phu tran không thể khớp với một ký tự bắt đầu bằng ký tự i
		    // kết quả : false
		    boolean resultStr2 = str2.matches("^i");
		    System.out.println("-Match ^i : " + resultStr2);
		    
		    String str3= "itphutrandotcom";
		    System.out.println("Chuỗi thứ ba là " + str3);
		    // kiểm tra chuỗi str3 có bắt đầu bằng 1 chuỗi bất kỳ
		    // quy tắc : .* - đại diện cho một chuỗi bất kỳ
		    // kết quả : true
		    boolean resultStr3 = str3.matches("^.*");
		    System.out.println("-Match .* : " + resultStr3);
		    
		    // kiểm tra toàn bộ chuỗi str3 có khớp với 1 ký tự m cuối cùng không
		    // quy tắc : $ 
		    // kết quả : false
		    boolean resultStr4 = str3.matches("m$");
		    System.out.println("-Match m$ : " + resultStr4);

		    // kiểm tra toàn bộ chuỗi str3 bắt đầu bằng một chuỗi bất kỳ và kết thúc bằng ký tự m
		    // quy tắc : $ 
		    // kết quả : false
		    boolean resultStr5 = str3.matches("^.*m$");
		    System.out.println("-Match ^.*m$: " + resultStr5);
		    
		    // bắt đầu bằng ký tự i tiếp theo là chuỗi bất kỳ gồm các ký tự  và kết thúc ký tự m
		    boolean resultStr6 = str3.matches("^i(.*).+m$");
		    System.out.println("-Match ^i(.*).+m$ : " + resultStr6);
	}
}

Kết quả :

Chuỗi thứ nhất là i
-Match ^i : true
Chuỗi thứ hai là it phu tran
-Match ^i : false
Chuỗi thứ ba là itphutrandotcom
-Match .* : true
-Match m$ : false
-Match ^.*m$: true
-Match ^i(.*).+m$ : true

Một số trường hợp chúng ta sử dụng để rewrite url nghĩa là đường dẫn trên url khi làm website,ví dụ các bạn có một chuỗi it phu tran và muốn thay đổi đường dẫn url đẹp thân thiện hơn như sau : it-phu-tran.Vậy các bạn cần sử dụng biểu thức chính quy trong java.Tiếp tục ví dụ trên tôi dùng  String.matches(String) như sau :

package regex;

public class SplitRegexExample3 {
	public static void main(String[] args) {
		String str  = "it phu tran";
		//đếm số khoảng trắng : kết quả = 3
		System.out.println(str.split("\\s+").length);
		String[] arStr = str.split("\\s+");
		// dùng replaceAll thay thế các ký tự khoảng trắng thành -
		str = str.replaceAll("\\s+", "-");
		System.out.println(str);
		
		// kết quả : 
		//3
		//it-phu-tran
	}
}

5.Sử dụng Pattern và Matcher

5.1- Định nghĩa

  •  Pattern là một đối tượng mẫu, một phiên bản đã được biên dịch của một biểu thức chính quy. Nó không có cấu tử (constructor) public, và chúng ta sẽ sử dụng method tĩnh compile(String) để tạo đối tượng, với tham số là biểu thức chính quy.
  • Matcher là một phương tiện để so khớp chuỗi dữ liệu đầu vào với đối tượng Pattern đã được tạo ra ở trên. Class này không có cấu tử public, và chúng ta lấy đối tượng này thông qua method matcher(String) của đối tượng Pattern. Với tham số đầu vào String là văn bản cần kiểm tra.
  •  PatternSyntaxException sẽ bị ném ra nếu biểu thức chính quy có ngữ pháp không chính xác.

5.2- Ví dụ

Tạo class PatternVsMatcherExampleEx1.java

package regex;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PatternVsMatcherExampleEx1 {
	public static void main(String[] args) {
		String regex= "(.*)phutran(.*)m$";
		// Tạo đối tượng Pattern thông qua method tĩnh.
		Pattern pattern = Pattern.compile(regex);
		// Lấy ra đối tượng Matcher
		Matcher matcher = pattern.matcher("iphutrandotcom");
		boolean match = matcher.matches();
		System.out.println("Match "+ match);
		// kết quả = true
	}
	
}

Chẳng hạn như với biểu thức chính quy regular expression trên,chúng ta cố tình thay đổi lại sai như sau thì chương trình ném ra ngoại lệ PatternSyntaxException :

String regex= "(.*s++++++++++++++)phutran(.*)m$";

PatternSyntaxException được ném ra

6.Các biểu thức chính quy thường gặp và hay sử dụng nhất trong java

 

1. Khoảng trống ở đầu và cuối

^ [ \ s ] + | [ \ s ] + USD
Sử dụng đoạn mã này để lấy ra khoảng chừng trắng ở đầu và cuối từ một chuỗi. Khi lập trình thường kiểm tra sai ở lỗi này, dễ gây nhầm lẫn. Sử dụng để tránh trường hợp thừa những khoảng chừng trống không đáng có .

2.Loại bỏ chú thích HTML – Regular Expression

– (. * ? ) –
Một số trường hợp những bạn cần vô hiệu những comment từ code HTML thì biểu thức trên là đáp án .

3.Xác thực ngày trong định dạng DD/MM/YYYY bằng biểu thức chính quy trong java

^ ( ? : ( ? : 31 ( \ / | – | \. ) ( ? : 0 ? [ 13578 ] | 1 [ 02 ] ) ) \ 1 | ( ? : ( ? : 29 | 30 ) ( \ / | – | \. ) ( ? : 0 ? [ 1,3 – 9 ] | 1 [ 0-2 ] ) \ 2 ) ) ( ? : ( ? : 1 [ 6-9 ] | [ 2-9 ] \ d ) ? \ d { 2 } ) $ | ^ ( ? : 29 ( \ / | – | \. ) 0 ? 2 \ 3 ( ? : ( ? : ( ? : 1 [ 6-9 ] | [ 2-9 ] \ d ) ? ( ? : 0 [ 48 ] | [ 2468 ] [ 048 ] | [ 13579 ] [ 26 ] ) | ( ? : ( ? : 16 | [ 2468 ] [ 048 ] | [ 3579 ] [ 26 ] ) 00 ) ) ) ) $ | ^ ( ? : 0 ? [ 1-9 ] | 1 \ d | 2 [ 0-8 ] ) ( \ / | – | \. ) ( ? : ( ? : 0 ? [ 1-9 ] ) | ( ? : 1 [ 0-2 ] ) ) \ 4 ( ? : ( ? : 1 [ 6-9 ] | [ 2-9 ] \ d ) ? \ d { 2 } ) USD
Để xác nhận ngày theo định dạng của biểu thức chính quy tất cả chúng ta sử dụng biểu thức regex trên để giải quyết và xử lý nhé .

3.Kiểm tra username có khoảng trống bằng biểu thức chính quy trong java – Regular Expression

Với username khi đăng nhâp vào mạng lưới hệ thống, chắn chắn cần phải kiểm tra username đó có khoảng chừng trắng không ? Nếu có sẽ không hợp lệ, biểu thức chính quy dưới đây được cho phép kiểm tra .
! str.matches ( “ \ \ S + ” )

4.Kiểm tra username bằng biểu thức chính quy trong java – Regular Expression

Username có độ dài tối thiểu 5 ký tự và tối đa 12 ký tự, không có khoảng chừng trắng, dấu tiếng việt .
=> ( min : 5 và max : 12 ký tự, không có dấu tiêng việt, không có khoảng trống ) :
[ a-z0-9_ – ] { 5,12 } $

5.Kiểm tra password bằng biểu thức chính quy trong java – Regular Expression

Nghiệp vụ kiểm tra mật khẩu – password có đúng format qui định hay không?
+ Phải chứa ít nhất 1 ký tự số từ 0 – 9
+ Phải chứa ít nhất 1 ký tự chữ thường
+ Phải chứa ít nhất 1 ký tự chữ hoa
+ Phải chứa ít nhất 1 ký tự trong tập các ký tự đặc biệt như: @#$%
+ Phải ít nhất là 06 ký tự và tối đa là 20 ký tự

( ( ? =. * \ \ d ) ( ? =. * [ a-z ] ) ( ? =. * [ A-Z ] ) ( ? =. * [ @ # USD % ! ] ). { 6,20 } )

6.Kiểm tra họ tên đầy đủ – FullName theo format qui định của biểu thức chính quy trong java  – Regular Expression

^ [ a-zA-Z \ \ sàáạã_ – ] { 3,25 } $

+ Chỉ chứa các ký tự a – z
+ Chỉ chứa các ký tự A – Z
+ Chứa ký tự khoảng trắng, unicode và ko chứa ký tự số

/**
* Nghiệp vụ kiểm tra thông tin FullName
* @param fullName
* @return – Họ và Tên không chứ ký tự số và tối thiểu là 03, tối đa là 25 ký tự

7.Kiểm tra thông tin Email có đúng format qui định?

^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@”
+ “[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$

Tổng kế t:

Qua bài viết này,các bạn cũng đã một phần nào đó hiểu về các định nghĩa cũng như cách sử dụng biểu thức chính quy trong java.Regular Expression rất phổ biến hiện nay nên việc không nắm bắt được cách sử dụng đối với một lập trình viên thì đó quả là một hạn chế.Hy vọng qua bài này,bạn đọc có một cái nhìn tổng quan hơn và áp dụng cho ứng dụng của mình.

Chúc các bạn học tốt!

Các bài viết tìm hiểu thêm :