Học Regular Expression và cuộc đời bạn sẽ bớt khổ - Phần 2

Học Regular Expression và cuộc đời bạn sẽ bớt khổ - Phần 2

Bạn ngứa tay muốn thử học RegEx ngay và luôn cho nóng. Vậy hãy thử thực hành bằng một số bài tập từ dễ đến khó sau đây nhé.

13 min read

Bắt 1 chuỗi bất kỳ nằm ở nhiều dòng (mutiline)

Biểu thức RegEx: <h1>[\s\S]*<\/h2>

Sẽ bắt được cả toàn bộ chuỗi nhiều dòng sau đây:

<h1>My First Heading</h1>
<p>My first paragraph.</p>
<h2>My first paragraph.</h2>

Giải thích tại sao lại bắt được. Rất đơn giản, là vì \s sẽ lấy được ký tự dấu cách, còn \S sẽ lấy được ký tự bất kỳ ngoại trừ dấu cách (và \S sẽ bắt được dấu xuống dòng \n). Nếu kết hợp 2 ký tự đó nhét vào một khung vuông [\s\S] tức là sẽ lấy được 1 trong 2 trường hợp. Sẽ bắt được toàn bộ các ký tự bất kỳ bao gồm cả dấu cách nếu gặp. Viết [\s\S]*? thật ra là nhân bản ký tự cần bắt lên nhiều lần để tìm một chuỗi dài vô tận.

Bình thường nếu tìm một chuỗi dài liên tiếp, không quan tâm là ký tự hay chữ số, ta hay viết là .*?, do đó cách viết [\s\S]*? thực ra là một biến thể của .*?. Dấu chấm . sẽ bắt được một ký tự bất kỳ ngoại trừ dấu xuống dòng, do đó .*? sẽ chỉ bắt được chuỗi dài vô tận ở cùng 1 dòng (1 line). Do đó nếu bạn cần bắt được chuỗi nằm ở nhiều dòng cho đến khi gặp một đoạn chuỗi cố định nào đó, thì sẽ phải dùng đến chiêu sau đây. Sử dụng [\s\S] để thay thế cho dấu . ta sẽ bắt được toàn bộ ký tự bất kỳ bao gồm cả dấu xuống dòng /n. Do đó để bắt được 1 chuỗi dài vô tận nằm ở nhiều dòng ta sẽ dùng [\s\S]*

Các bạn có thể xem link demo: https://regex101.com/r/irhKCk/1

Sử dụng RegEx trong thực tế

Trong thực tế RegEx có thể được gõ trực tiếp ở bất kỳ trình Editor nào. Ví dụ mình hay dùng Notepad++, hoặc Visual Studio

Thêm thật nhiều ví dụ cho bạn tham khảo (để xem sức mạnh của RegEx)

Check một chuỗi ngày tháng bất kỳ có hợp lệ hay không tính theo năm nhuận

Biểu thức RegEx:

^(((0?[1-9]|1[012])/(0?[1-9]|1\d|2[0-8])|(0?[13456789]|1[012])/(29|30)|(0?[13578]|1[02])/31)/(19|[2-9]\d)\d{2}|0?2/29/((19|[2-9]\d)(0[48]|[2468][048]|[13579][26])|(([2468][048]|[3579][26])00)))$

Sẽ đúng cho:

01/31/1905 | 1/9/1900 | 2/29/1904

Và sẽ không trùng với:

31/01/2005 | 02/29/2005 | 2/29/2005

Check 1 chuỗi ngày tháng phải có cả ngày và giờ

Biểu thức RegEx:

^(?=\d)(?:(?:31(?!.(?:0?[2469]|11))|(?:30|29)(?!.0?2)|29(?=.0?2.(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(?:\x20|$))|(?:2[0-8]|1\d|0?[1-9]))([-./])(?:1[012]|0?[1-9])\1(?:1[6-9]|[2-9]\d)?\d\d(?:(?=\x20\d)\x20|$))?(((0?[1-9]|1[012])(:[0-5]\d){0,2}(\x20[AP]M))|([01]\d|2[0-3])(:[0-5]\d){1,2})?$

Sẽ đúng cho:

31/12/2003 11:59:59 PM | 29-2-2004 | 01:45:02

Và sẽ không trùng với:

12/31/2003 | 29.02.2005 | 13:30 PM

Check 1 chuỗi bất kỳ xem có phải ngày hoặc giờ hay không

Biểu thức RegEx:

^(?=\d)(?:(?!(?:(?:0?[5-9]|1[0-4])(?:\.|-|\/)10(?:\.|-|\/)(?:1582))|(?:(?:0?[3-9]|1[0-3])(?:\.|-|\/)0?9(?:\.|-|\/)(?:1752)))(31(?!(?:\.|-|\/)(?:0?[2469]|11))|30(?!(?:\.|-|\/)0?2)|(?:29(?:(?!(?:\.|-|\/)0?2(?:\.|-|\/))|(?=\D0?2\D(?:(?!000[04]|(?:(?:1[^0-6]|[2468][^048]|[3579][^26])00))(?:(?:(?:\d\d)(?:[02468][048]|[13579][26])(?!\x20BC))|(?:00(?:42|3[0369]|2[147]|1[258]|09)\x20BC))))))|2[0-8]|1\d|0?[1-9])([-.\/])(1[012]|(?:0?[1-9]))\2((?=(?:00(?:4[0-5]|[0-3]?\d)\x20BC)|(?:\d{4}(?:$|(?=\x20\d)\x20)))\d{4}(?:\x20BC)?)(?:$|(?=\x20\d)\x20))?((?:(?:0?[1-9]|1[012])(?::[0-5]\d){0,2}(?:\x20[aApP][mM]))|(?:[01]\d|2[0-3])(?::[0-5]\d){1,2})?$

Sẽ đúng cho:

31.12.6008 | 5:30 AM | 30-04-1066

Và sẽ không trùng với:

00/00/0000 | 99:99:99 | 29/02/2005

Tóm lại:

  • Regular expressions (hay còn gọi là Biểu thức chính quy – viết tắt là RegEx) là một chuỗi ký tự đặc biệt được dùng làm mẫu (pattern) để phân tích sự trùng khớp (match) của một tập hợp các chuỗi con cần lấy ra từ một chuỗi cha.
  • Chuỗi cha sau khi kiểm tra và lấy ra được các chuỗi con thì kết quả được đưa vào các Nhóm kết quả (Matches).
  • Trong mỗi Matches có các Group chứa các chuỗi con có thể cut lấy ra khỏi chuỗi cha (do người dùng định nghĩa chuỗi con cần lấy hoặc không lấy bằng cách viết thêm cặp ngoặc tròn () bao bọc chuỗi con cần lấy)
  • RegEx có thể lấy chuỗi ra (cut) hoặc thay thế chuỗi (replace)
  • Hầu hết những ngôn ngữ lập trình (PHP, C#, Perl, Javascript…) đều cung cấp các thư viện hoặc hàm xử lý để lập trình viên có thể làm việc với Regular expression.

Tham khảo

Tham khảo thêm toàn bộ cú pháp RegEx bằng tiếng Anh tại: https://www.cheatography.com/davechild/cheat-sheets/regular-expressions/

Một số công cụ test RegEx Online

Bài tập về nhà

Bạn ngứa tay muốn thử học RegEx ngay và luôn cho nóng. Vậy hãy thử thực hành bằng một số bài tập từ dễ đến khó sau đây nhé.

Bài tập nhập môn:

  1. Lấy ra các chữ có chữ test trong chuỗi sau: “that tested test is testing the tester's tests”
  2. Lấy ra các số điện thoại trong chuỗi sau: ** “p:444-555-1234 f:246.555.8888 m:1235554567”**
  3. Lấy ra các mã màu RGB trong chuỗi sau: “#FF006C ABC 99AAB7FF 0xF0F73611”
  4. Lấy ra các chữ có 4 ký tự trong chuỗi sau: “drink beer, it's very nice!”
  5. Lấy ra tên file trong chuỗi URL sau: rapidshare.com/asd/asd/File.avi.html”
Đáp án ở phần comment nhé.

Bài tập dành cho học sinh giỏi (lớp học thêm)

  1. Tìm cách lấy các URL trong chuỗi HTML sau:
Lorem gyum
<b>Betrag</b> von 
<a href="http://www.vektor.de">Vektoren</a>
(Länge eines Vektors)
<a href="gcfa.com">GCFA</a> 
<a href="//cdn.com/test.js">CDN</a> 
ist das Maß einer Menge sozu…
  1. Tìm cách loại bỏ toàn bộ COMMENT trong đoạn code sau:
var sample = 0; 
var my_string = "Hello World!"; 
// This is a comment! 
function do_stuff(){ 
// This is another comment! 
alert(‘somethings’);
/* this is a multiline
     comment */
}
  1. Tìm cách lấy ra chuỗi tiếng Nhật trong chuỗi sau: “
This is a demo story 前に来た時は北側からで、当時の光景はいまでも思い出せる。And it is true.
  1. Lấy ra những file ảnh và độ phân giải của ảnh từ chuỗi sau:
.bash_profile
workspace.doc
img0912.jpg (1280x720)
updated_img0912.png (1024x768)
documentation.html
favicon.gif 
img0912.jpg (1920x1600)
access.htaccess
  1. Đọc nội dung từ trang tin rss sau: http://rss.cnn.com/rss/edition.rss Lấy ra các Tiêu đề, ngày giờ đăng, nội dung tin vắn
Đáp án các bạn post vào phần comment và cùng trao đổi nhé.

Nếu các bài tập trên đây vẫn chưa đủ, các bạn hãy làm thêm các bài tập tại trang https://regexone.com nhé, rất nhiều ví dụ hay.

Kết bài

Hi vọng bài viết nhỏ này đã giúp bạn học được cú pháp viết RegEx và áp dụng vào công việc thường ngày. Mình dùng Regex rất nhiều và nó là trợ thủ đắc lực trong quá trình code.

Các bạn thì sao? bạn đã dùng Regex vào những việc gì? Hãy kể tên bên dưới comment để mình cùng học hỏi với nhé.

Thanks các bạn đã đọc, hãy comment, upvote và share bạn bè thật nhiều nhé!

Update v2.2: Thêm các bài tập để các bạn luyện thêm (theo yêu cầu của nhiều bạn, nhớ tự làm trước khi dòm đáp án nhé ^^!)

BTU1. Tìm ra các chuỗi là số điện thoại trong chuỗi sau. Chú ý một số loại ra một số chuỗi không phải là số điện thoại

Positive:
+42 555.123.4567
+1-(800)-123-4567
+7 555 1234567
+7(926)1234567
(926) 1234567
+79261234567
926 1234567
9261234567
1234567
123-4567
123-89-01
495 1234567
469 123 45 67
89261234567
8 (926) 1234567
926.123.4567
415-555-1234
650-555-2345
(416)555-3456
202 555 4567
4035555678
1 416 555 9292
11234567890
123-456-7890
(123) 456-7890
1 (123) 456-7890
123 456 7890
1 123 456 7890
123.456.7890
1 123.456.7890
1.123.456.7890
+1 123.456.7890
+91 (123) 456-7890
+1-(800)-555-2468
1-234-567-8912
+22-432-359-3687

Negative:
926 3 4
8 800 600-APPLE

Lời giải https://regexr.com/38pvb

BTU2. Tìm ra chuỗi là địa chỉ email trong chuỗi sau, chú ý loại bỏ các chuỗi k phải địa chỉ emai thực sự.

Acceptable
---------------
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]

Non-Acceptable
---------------
abc@@insta.com.com.com
[email protected]
abc@insta%.com
abc@insta/.com
abc@insta\\.com
[email protected] 
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
abc%@insta.com
abc\\@insta.com
abc/@insta.com
[email protected]
[email protected]

Lời giải: https://regexr.com/3bcrb

BTU3. Tìm cách lấy ra và ngăn cách chuỗi số sau thành có phần trăm phần nghìn.

12345678

Toi muon no tro thanh 12,345,678

Lời giải: regexr.com/4409r

BTU4. Lấy ra các chuỗi ngăn cách bởi dấu phẩy theo định dạng của một file CSV như sau (chú ý là chuỗi bị xuống dòng):

12,\"Hello, my name is Borislav.\",\"\"\"Welc
ome\"\"\",\"welcome\",   what\'s up!
new entry

Lời giải: https://regexr.com/3apuc

BTU5. Tìm và xóa đi toàn bộ các thẻ HTML trong đoạn text dưới đây:

Welcome to RegExr v2.0 by gskinner.com!
 Welcome
Edit the Expression & Text to see matches. Roll over matches or the expression for details. Undo mistakes with ctrl-z. Save & Share expressions with friends or the Community. A full Reference & Help is available in the Library, or watch the video Tutorial.

Sample text for testing:
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ
xyz
xy
xy
xy
xy
0123456789 _+-.,!@#$%^&*();\\/|<>\"\'
12345 -98.7 3.141 .6180 9,000 +42
555.123.4567	+1-(800)-555-2468
[email protected]	[email protected]
www.demo.com	http://foo.co.uk/
http://regexr.com/foo.html?q=bar
<!DOCKTYPE html>
<html>
	<head>
		< title> My website </title>
		<link >
	</head>
	<body>
		<h1> Hello World </h1>
		<p> goodbye world</p>
	</body>
</html>

<!DOCTYPE html>
<html>
  <head>
    <!--Устанавливаю кодировку-->
    <meta charset-\"utf-8\">
    <!--Устанавливаю заголовок-->
    <title>How Long You Life?</title>
    <!--Подключаею стили-->
    <link rel=\"stylesheet\" href=\"css/style.css\">
    <link rel=\"shortcut icon\" href=\"img/favicon.ico\" type=\"image/x-icon\">
  </head>
  <body>
    <div id=\"main\">
      <div id=\"head\">How much you have to live?</div>
      <div id=\"text\">Days Hours Min Sec</div>
      <div id=\"time\"></div>
    </div>    
    <script src=\"js/script.js\"></script>    
  </body>
</html>

Lời giải: https://regexr.com/3cak1

BTU6. Tìm cách loại bỏ các chuỗi console.log() do lập trình viên viết để test ra khỏi code trước khi bàn giao

function(window,document, this) {
console.log(\"This should be only in debug mode);
anotherCode();
console.log(\"this
too\" + var +
\" =)\");
var variable;
console.
log(\"debug mode\");
do(foo);
console.
log(\"this was\" +
\" formatted\" +
 \" by \" + ideFormatter);
 
}(window, console, this));

Lời giải: https://regexr.com/3fi66

BTU7. Loại bỏ toàn bộ các đoạn comment code trong đoạn code sau đây:

var sample    = 0;
var new       = 1;
var my_string = \"Hello World!\";

// This is a comment!

function do_stuff(){
	alert(my_string);//another comment
}

/* This is
 * a multiline
 * comment!
 */

var something;

/* programs/applications 16/*(4*2)=2 */

if(sample > new){
  do_stuff(/* arguments here */);
}

//

/**/

Lời giải: https://regexr.com/3aeb7

BTU8. Lấy ra các chuỗi là các URL đầy đủ trong đoạn text dưới đây:

Welcome to RegExr 0.3b, an intuitive tool for learning, writing, and testing Regular Expressions. Key features include: 
www.google.com
* real time results: shows results as you type 
* code hinting: roll over your expression to see info on specific elements 
* detailed results: roll over a match to see details & view group info below 
* built in regex guide: double click entries to insert them into your expression 
* online & desktop: regexr.com or download the desktop version for Mac, Windows, or Linux 
* save your expressions: My Saved expressions are saved locally 
* search Comm https://google.us.edi?34535/534534?dfg=g&fg unity expressions and add your own 
* create Share Links to send your expressions to co-workers or link to them on Twitter or your blog [ex. http://RegExr.com?2rjl6] 

Built by gskinner.com with Flex 3 [adobe.com/go/flex] and Spelling Plus Library for text highlighting [gskinner.com/products/spl].

Lời giải: https://regexr.com/39nr7

BTU9. Lấy ra toàn bộ các URL của một video Youtube từ đoạn text test sau đây

video complex
https://www.youtube.com/watch?feature=something&v=videoid1&embed=something
http://www.youtube.com/watch?feature=something&v=videoid2&embed=something
www.youtube.com/watch?feature=something&v=videoid3&embed=something
youtube.com/watch?feature=something&v=videoid4&embed=something

video
https://www.youtube.com/watch?v=videoid1
http://www.youtube.com/watch?v=videoid2
www.youtube.com/watch?v=videoid3
youtube.com/watch?v=videoid4

other video
https://www.youtube.com/v/videoid1
http://www.youtube.com/v/videoid2
www.youtube.com/v/videoid3
youtube.com/v/videoid4

channel
https://www.youtube.com/channel/channelid1
http://www.youtube.com/channel/channelid2
www.youtube.com/channel/channelid3
youtube.com/channel/channelid4

user
https://www.youtube.com/user/username1
http://www.youtube.com/user/username2
www.youtube.com/user/username3
youtube.com/user/username4

search
https://www.youtube.com/results?search_query=search+query1
http://www.youtube.com/results?search_query=search+query2
www.youtube.com/results?search_query=search+query3
youtube.com/results?search_query=search+query4

Youtu.be video
https://youtu.be/videoid1
http://youtu.be/videoid2
youtu.be/videoid3

normal youtube link
https://www.youtube.com
http://www.youtube.com
www.youtube.com
youtube.com

Youtu.be link
https://youtu.be
http://youtu.be
youtu.be

Lời giải: https://regexr.com/3akf5

BTU10. Lấy ra các đoạn text là giá trị màu RBG

Should match 3 ou 6 digits hexadecimal numbers
#fff #FFF #Fff #ff004B
All numerical values can have leading zeros. Percentages can have decimals.
White spaces are allowed before and after values.
Should match rgb() colors with 3 values all between 0 and 255
rgb(0,0,0) RGB(124, 100, 0) rgb(255,255,255) Rgb( 0255, 00001, 02)
Should match rgb() colors using percentages all between 0 and 100
rgb(10%,10%,10%) rgb(100.0%, 2.5%, 0%) rgb(00010%, 0002%, 001%)
Should match rgba() colors with 3 values between 0 and 255 plus 1 decimal value between 0 and 1
rgba(255 , 0 , 0, 0.5 ) rgba(1,1,1,0.255) rgba(0,0,0,0)
Should match rgba() colors using 3 percentage values between 0 and 100 plus 1 decimal value between 0 and 1
rgba(10%,10% , 10%, 0.2) rgba(10%, 0025.2%, 1%, 0.0001)
Should match hsl() colors with first value between 0 and 360 and 2 more percentage values between 0 and 100
hsl(0,20%,100%) HsL(360,10% , 0.2% ) hsl(000350, 002%, 0004.1%)
Should match hsl() colors with first value between 0 and 360 and 2 more percentage values between 0 and 100 plus 1 decimal value between 0 and 1
hsla(140,2%,50%,0.2) hsla(0,0%,0%,0) hsla(001,002%,00001.2%,0000.254)

Should NOT match hexadecimal numbers with not exactly 3 or 6 digits
#f #ff #ffff #fffff #fffffff
Should NOT match invalid hexadecimal values
#ffg #fffffg
Should NOT allow space between function and opening parenthesis
rgb (0,0,0) rgba (0,0,0,0) rgb (0%,0%,0%) rgba (0%,0%,0%,0) hsl (0,0%,0%) hsla (0,0%,0%,0)
Should NOT match rgb() nor hsl() colors with more or less than 3 values
rgb(0,0,0,0) rgb(0,0) hsl(0,0%,0%,0) hsl(0,0%)
Should NOT match rgba() nor hsla() colors with more or less than 4 values
rgba(0,0,0) rgba(0,0,0,0,0) hsla(0,0%,0%) hsla(0,0%,0%,0,0)
Should NOT allow rgb values over 255, nor rgb values with decimals
rgb(256,0,0) rgb(100.2,0,0)
Should NOT allow percentages over 100
rgb(120%,10%,1%) hsl(200, 101%, 10%)
Should NOT allow alpha values over 1
rgba(0,0,0,1.2) hsla(120, 50%, 50%, 1.3)
Should NOT allow hue values over 360
hsl(361,50%,50%) hsla(361,50%,50%,0.5)
Should NOT match invalid hsl format
hsl(1%,2%,3%) hsl(5,6,7)
Should NOT match rgb() colors with mixed percentages and integers
rgb(255, 10%, 0) rgb(10%, 255, 0) rgba(10%, 255, 0, 0.3)

Lời giải: https://regexr.com/38lmo

Theo viblo.asia

Related Articles

RESTful: Phần 4 - API Rate Limiting
10 min read
RESTful: Phần 3 - API Caching
12 min read
The queue data structure
3 min read

GO TOP

🎉 You've successfully subscribed to itplusX!
OK
]