SlideShare ist ein Scribd-Unternehmen logo
1 von 11
Regular Expressions
1. Regular expression là gì?
+ Biểu thức chính quy.
+ Hiểu nôm na là 1 chuỗi có quy tắc để mô tả những chuỗi(string) khác
2. Cú pháp cơ bản (ở đây mình chỉ trình bày và ví dụ cho ngôn ngữ php)
Example:
PHP Code:
<?php
$re = '/hello/'; // biểu thức chính quy cho một string có chuỗi “hello” ở trong đó.
$str = 'hello world';
if(preg_match($re, $str)) {
echo 'Yes';
}
?>
Output: Yes
+ Ký hiệu “^” và “$”: bắt đầu và kết thúc 1 string
Example:
PHP Code:
<?php
$re = '/^hello/'; // biểu thức chính quy cho một string bắt đầu bởi chuỗi “hello”
$str = 'hello world';
if(preg_match($re, $str)) {
echo 'Yes';
}
else {
echo 'No';
}
?>
Output: Yes
PHP Code:
<?php
$re = '/hello$/'; // biểu thức chính quy cho một string kết thúc bởi chuỗi “hello”
$str = 'hello world';
if(preg_match($re, $str)) {
echo 'Yes';
}
else {
echo 'No';
}
?>
Output: No
+ Ký hiệu: “*”, “+”, “?”
$re = '/^ab*$/' ; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 0 hoặc
nhiều b (ví dụ: a, ab, abb, abbb, …);
$re = '/^ab+$/' ; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 1 hoặc
nhiều b (ví dụ: ab, abb, abbb, …);
$re = '/^ab?$/' : // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là b hoặc
là không (ví dụ: ab hoặc a).
Example:
PHP Code:
<?php
$re = '/^ab*$/';
$str = 'abbc';
if(preg_match($re, $str)) {
echo 'Yes';
}
else {
echo 'No';
}
?>
Output: No
+ Sử dụng: {}:
$re = '/^ab{2}$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 2 chũ
b (là abb);
$re = '/^ab{2,}$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là ít
nhất 2 chũ b (ví dụ: abb, abbb, abbbb, …);
$re = '/^ab{2,5}$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là ít
nhất 2 chũ b và nhiều nhất là 5 chữ b (ví dụ: abb, abbb, abbbb, abbbbb);
+ Sử dụng : () và |
$re = '/^a(bc)*$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 0
hoặc nhiều 'bc' (ví dụ abc, abcbc, abcbcbcbc, …)
$re = '/^a(b|c)*$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 0
hoặc nhiều 'b' hoặc nhiều 'c' hoặc 'b' 'c' lẫn lộn :D (ví dụ abc, abbcccccccccc,
abccccbbbcbc, …)
+ Sử dụng symbol '.': đại diện cho một ký tự đơn bất kỳ
$re = '/^.{3}$/'; //Biểu thức chính quy cho một chuỗi có đúng 3 ký tự bất kỳ.
PHP Code:
<?php
$re = '/^.{3}$/';
//Biểu thức chính quy cho một chuỗi có đúng 3 ký tự bất kỳ.
$str = '&#%';
if(preg_match($re, $str)) {
echo 'Yes';
}
else {
echo 'No';
}
?>
Output: Yes
+ Sử dụng: '-':
[0-9] : Một chữ số
[a-zA-Z]: một ký tự A->Z, a->z
[a-d] : ~ (a|b|c|d)
[^a-zA-Z]: một ký tự không phải là A->Z, a->z
[^0-9]: một ký tự không phải là số
+ Sử dụng: ''
d - Chữ số bất kỳ ~ [0-9]
D - Ký tự bất kỳ không phải là chữ số (ngược với d) ~ [^0-9]
w - Ký tự từ a-z, A-Z, hoặc 0-9 ~ [a-zA-Z0-9]
W - Ngược lại với w (nghĩa là các ký tự không thuộc các khoảng: a-z, A-Z, hoặc 0-9)
~[^a-zA-Z0-9]
s - Khoảng trắng (space)
S - Ký tự bất kỳ không phải là khoảng trắng.
3. Các hàm cơ bản vận dụng regular expression
+ preg_match : http://php.net/manual/en/function.preg-match.php
int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int
$offset = 0 ]]] )
Cơ bản là để tìm kiếm 1 string có làm việc theo một $re.
Ví dụ:
PHP Code:
<?php
$re = '/^w+$/';
// một string toàn ký tự A->Z, a->z, 0->9
$str = 'quya*';
if(preg_match($re, $str)) {
echo 'Yes';
}
else {
echo 'No';
}
?>
Output: No
+ preg_replace: http://www.php.net/manual/en/function.preg-replace.php
mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit
= -1 [, int &$count ]] )
Cơ bản là để tìm kiếm trong 1 string những chuỗi có cấu trúc theo $re để thay thế
Ví dụ:
PHP Code:
<?php
$re = '/w+$/';
$str = '*quya';
echo preg_replace($re, 'hi', $str);
?>
Output: *hi
+ preg_split: http://php.net/manual/en/function.preg-split.php
array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] )
Ví dụ:
Các bạn xem tạm ví dụ ở trong php manual nhé. Mệt rùi.
Để viết ra bài này, mình đã tham khảo nhiều nguồn trên mạng, và kiến thức từ những lần
sử dụng regular expressions.
Có zì sai hay chưa đủ thì các bạn pm để mình bổ xung thêm.
Giới thiệu Regular Expression Nâng cao
I. Thêm comment vào biểu thức Regular Expression:
Trong trường hợp biểu thức chính quy của bạn quá dài. Và muốn sau này người dùng sau
có thể hiểu và chỉnh sửa lại (reuse), thì chúng ta cần phải ghi chú lại. hì hì.
Để thêm comment vào 1 biểu thức Regular Expression hiện giờ có 2 cách thì phải.
- Sử dụng cú pháp (?# nội dung ghi chú).
Ví dụ: kiểm tra ngày có đúng định dạng dd/mm/yyyy không ta có parttern sau:
Mã:
$parttern = “/^d{2}/d{2}}/d{4}$/” //cái này ngắn quá
tham khảo thôi.
Sau khi thêm comment vào:
Mã:
$parttern = “/^d{2}(?# ngày là số nguyên 2 kí
tự)/d{2}(?# Tháng là số nguyên 2 kí tự)/d{4}(?# Năm là
số nguyên 4 kí tự)$/”
- Cách này nhìn sáng sủa và dễ hiểu hơn:
Mã:
$parttern = “/^
d{2} # ngày là số nguyên 2 kí tự
/ # dấu phân cách “/”
d{2} # Tháng là số nguyên 2 kí tự
/ # dấu phân cách “/”
d{4} # Năm là số nguyên 4 kí tự
$/x”; // Sử dụng modifier là x.
Khi sử dụng modifier x thì khoảng trắng trong biểu thức chính quy sẽ được bỏ qua, nếu
không nó sẽ được escaped (s). Điều này dễ dàng để thêm comment. Comment sẽ bắt đầu
bằng dấu “#” và kết thúc tại 1 dòng mới.
II. Greedy và Ungreedy:
Để hiểu được phần này bạn cần xem qua ví dụ sau:
Ví dụ: Mình có 1 đoạn mã html sau khi view source của 1 trang web
Mã:
<html>
<head><title>Greedy và Ungeedy</title></head>
<body>
<p id=”weather”>
Nội dung cần lấy nằm ở đây
</p>
<p>
Nội dung khác
</p>
</body>
</html>
Vậy để lấy nội dung trong thẻ <p id=”weather”></p>, mình sẽ phải viết biểu thức sau:
PHP Code:
$parttern = “/<p id=”weather”>(.*)</p>/s”;
if(preg_match($parttern, $html, $match))
{
print_r($match);
}
Hì hì, kết quả thế nào các bạn sẽ lấy được nội dung cần lấy chứ.
Mã:
Array (
[0] =>
Nội dung cần lấy ở đây
Nội dung khác
[1] =>
Nội dung cần lấy ở đây
Nội dung khác
)
Như vậy, nội dung mình cần lấy vẫn chưa lấy được, tìm hiểu nguyên nhân tại sao:
Xem lại $parttern của mình: $parttern = “/<p id=”weather”>(.*)</p>/s”;
Mô tả parttern: bắt đầu bằng thẻ p có id=”weather”, tiếp sau là nội dung bắt kì có thể có
nhiều hoặc không có kí tự nào và kết thúc là html tag </p>.
Khi dùng modifier s: cho biết so khớp parttern với mọi kí tự kể cả kí tự xuống dòng, nếu
không có nó kí tự xuống dòng sẽ bị loại trừ.
- Mặc định trong so khớp mẫu thì nó sẽ lấy thẻ p có id = "weather" và nội dung bất kì bên
trong đến khi gặp tag đóng </p>. Nhưng phải là tag đóng </p> cuối cùng thì nó mới dừng
lại (Greedy, tiếng việt là tham lam, tham ăn gì đó) so tới cuối luôn đó mà.
- Vậy làm sao để parttern hiểu rằng khi so khớp mình chỉ lấy nội dung bất kì giữa 2 tag
<p id="weather">nội dung đến tag đóng </p> đầu tiên thôi. Lúc đó, mình sẽ dùng kí tự
dấu hỏi "?" (Ungreedy) để thêm vào sau quantifier của parttern muốn so khớp. Hì hì Cái
quantifier tham khảo lại nha, vì bài này đang hướng dẫn Advanced Regular Expression
mà.
- Vì vậy để lấy được nội dung chính xác với parttern của mình
Mã:
$parttern = '/<p id="weather">(.*)</p>/s';
thì mình chỉ cần thêm dấu hỏi sau quantifier "*" là xong.
Mã:
$parttern = '/<p id="weather">(.*?)</p>/s';
Chạy lại code
PHP Code:
$parttern = “/<p id=”weather”>(.*?)</p>/s”;
if(preg_match($parttern, $html, $match))
{
print_r($match);
}
bạn sẽ nhận được kết quả như ý
Mã:
Array (
[0] =>
Nội dung cần lấy ở đây
[1] =>
Nội dung cần lấy ở đây
)
III. Lookahead and Lookbehind Assertions (được gọi chung là lookaround)
1. Positive and Negative Lookahead:
- cú pháp: positive lookahead (?=), negative lookahead (?!)
- Bạn có thể xem qua ví dụ để hiểu rõ hơn:
Mã:
$parttern = "/hellos*(?=world)/";
- Ý nghĩa: đầu tiên mẫu sẽ so khớp bắt đầu bằng hello, tiếp theo sẽ là có thể có nhiều
hoặc không có khoảng trắng, và cuối cùng theo sau nó có phải là world không. Các bạn
thấy đó, $parttern để thực hiện mục đích này không thật sự hữu dụng vì sao, chúng ta
không cần biết lookahead thì vẫn thực hiện được với:
Mã:
$parttern = "/hellos*world/";
điều này là sai lầm. hì hì. Nếu bạn chỉ muốn tìm xem chuỗi có đúng như vậy không, chỉ
nhận về kết quả true hoặc false là có thể bạn cho là sử dụng lookahead lúc này là không
có khả dụng. Tuy nhiên, nếu đi sâu vào hơn, bạn sử dụng kết quả trả về của code:
PHP Code:
$chuoi = "hello world";
$parttern = "/hellos*(?=world)/";
$parttern1 = "/hellos*world/";
if(preg_match($parttern, $chuoi))
{
echo "valid";
}
// tương đương với
if(preg_match($parttern1, $chuoi))
{
echo "valid";
}
Nhưng nếu bạn muốn sử dụng kết quả trả về. Ở đây mình lấy ví dụ của bài đầu Greedy và
Ungreedy
Mã html sau khi viewsource 1 trang web
PHP Code:
//tạo biến $html giữ nội dung trang web.
$html = '<html>
<head><title>Greedy và Ungeedy</title></head>
<body>
<p id=”weather”>
Nội dung cần lấy nằm ở đây
</p>
<p>
Nội dung khác
</p>
</body>
</html>';
và nội dung trả về sau khi thực hiện đoạn code là gì nhỉ các bạn
PHP Code:
$parttern = “/<p id=”weather”>(.*?)</p>/s”;
if(preg_match($parttern, $html, $match))
{
print_r($match[0]);
}
kết quả:
Mã:
Nội dung cần lấy ở đây
Có phải nội dung bạn cần lấy là nội dung nằm giữa thẻ <p id="weather"> và thẻ đóng
</p>. Nhìn kết quả xuất ra khi dùng print_r($match[0]). các bạn cho rằng là đúng. Mình
cũng thấy đúng mà, nhưng khi bạn view source thử xem, kết quả thế nào nhỉ. không tồi,
hihi
kết quả viewsource
Mã:
<p id="weather">
Nội dung cần lấy nằm ở đây
</p>
Kết quả là nó lấy luôn thẻ p đóng và mở àh các bạn, vậy làm sao mẫu so khớp vẫn kiểm
tra đúng mà kết quả trả về, mình sẽ loại bỏ cái tag p đóng và mở àh nhỉ.
--> lookahead and lookbehind was born. (rồi thấy được công dụng nha các bạn).
- Sửa lại cấu trúc $parttern
PHP Code:
$parttern_old = '/<p id="weather">(.*?)</p>/s';
$parttern_new = '/(?<=<p id="weather">)(.*?)(?=</p>)/s';
- Giải thích $parttern_new: lấy nội dung bất kì mà theo trước nó là tab mở <p
id="weather"> và theo sau nó là tag đóng </p> (Không bao gồm tag mở và đóng nha
bạn).
2. Positive and Negative Lookbehind:
- Cú pháp: positive lookbehind (?<=), negative lookbehind.
- Mình chỉ đưa ra ví dụ và nêu ý nghĩa, giống ở trên các bạn tìm hiểu nha.
(?<!)
IV. Conditional (If-Then-Else) Patterns
- Regular Expression cung cấp cho chúng ta chức năng kiểm tra điều kiện.
- Cú pháp: (?(condition)true-pattern|false-pattern) hoặc (?(condition)true-pattern)
- Giải thích: nếu condition đúng thì so khớp true-parttern, ngược lại so khớp với false-
parttern.
ví dụ:
PHP Code:
// nếu bắt đầu với h thì , so khớp he
// ngược lại so khớp với she
$pattern = '/^(?(?=h)he|she)/';
preg_match($pattern, 'he'); // true
preg_match($pattern, 'she'); // true
preg_match($pattern, 'shoes'); // false
- chú ý: điều kiện condition có thể là 1 con số. Trong trường hợp này, nó sẽ tham chiếu
đến capture subpartter ở phía trước nó.
ví dụ:
PHP Code:
// parttern (a)?b(?(1)c|d) khớp với bd và abc. nhưng nó khô
ng khớp với bc
$parttern = "(a)?b(?(1)c|d)";
preg_match($pattern, 'bd'); // true
preg_match($pattern, 'abc'); // true
preg_match($pattern, 'bc'); // false
- Phân tích: $pattern = "(a)?b(?(1)c|d)";
bắt đầu bằng 1 subparttern (a) hoặc không có theo sau là b và cuối là 1 parttern if-else
condition (?(1)c|d).
- Giải thích:
PHP Code:
$parttern = "(a)?b(?(1)c|d)";
preg_match($pattern, 'bd');
/* so khớp parttern với chuỗi 'bd'.
ta thấy, bắt đầu bằng b vì subpartter a có thể có hoặc khô
ng,
tiếp đến là condition số 1 sẽ tham chiếu tới subparrtern a
ở phía trước,
vì không có a nên (?(1)c|d) sẽ trả về kết quả false,
nên biểu thức tiếp tục so khớp với d.
và kết thúc chuỗi là d nên thỏa => kết quả true
*/
V. Non-capturing Subpatterns
- Cú pháp: (?:subparttern)
- Subparttern kèm theo dấu ngoặc đơn, được lưu giữ vào 1 mảng để chúng ta có thể sử
dụng chúng sau này khi cần thiết. Nhưng đối với những biểu thức chúng ta chỉ muốn giữ
những giá trị của subparttern cần thiết, và không lưu lại những giá trị của parttern khác,
chúng ta sẽ sử dụng cú pháp ở trên (?:subparttern) (gọi là non - capturing subparttern).
- Các bạn xem ví dụ sau để dễ hiểu hơn:
PHP Code:
preg_match('/(f.*)(b.*)/', 'Hello foobar', $matches);
echo "f* => " . $matches[1]; // prints 'f* => foo'
echo "b* => " . $matches[2]; // prints 'b* => bar'
- Thay đổi 1 chút bằng cách thêm 1 subparttern (H*) ở phía trước
PHP Code:
preg_match('/(H.*) (f.*)(b.*)/', 'Hello foobar', $matches);
echo "f* => " . $matches[1]; // prints 'f* => Hello'
echo "b* => " . $matches[2]; // prints 'b* => foo'
- Mảng $matches lúc này đã thay đổi, giá trị của subparttern (H*) được giữ lại và tương
ứng với chỉ số của mảng $matches là $matches[1]. Chúng ta thực sự không muốn giữ lại
giá trị của subparttern này chúng ta chỉ cần làm cho nó thành non - capturing subparttern
bằng cách:
PHP Code:
preg_match('/(?:H.*) (f.*)(b.*)/', 'Hello foobar', $matches
);
echo "f* => " . $matches[1]; // prints 'f* => foo'
echo "b* => " . $matches[2]; // prints 'b* => bar'
VI. Named Subpatterns
- Cú pháp: (?P<named_subparttern>subpattern)
- sau khi lấy giá trị của subparttern gán vào biến $matches, nếu chúng ta muốn truy xuất
đến các giá trị của subpattern bằng tên thì chúng ta sử dụng cú pháp trên. Việc sử dụng
tên của subpattern sẽ dễ dàng cho chúng ta quản lý và truy xuất hơn.
- Các bạn xem ví dụ sau:
PHP Code:
$html='
ip: 192.168.1.1
name: truong-pc
ip: 192.168.1.2
name: thuy
';
$patternip = '/(?P<ip>(?<=ip:)s*d+.d+.d+.d+)/';
preg_match_all($patternip,$html, $matches);
echo "<pre>";
print_r($matches);
echo "</pre>";
- Mảng $matches sẽ có giá trị
Mã:
Array
(
[0] => Array
(
[0] => 192.168.1.1
[1] => 192.168.1.2
)
[ip] => Array
(
[0] => 192.168.1.1
[1] => 192.168.1.2
)
[1] => Array
(
[0] => 192.168.1.1
[1] => 192.168.1.2
)
)
- Khi đó chúng ta muốn lấy giá trị của subparttern ip chúng ta chỉ cần truy cập
$matches['ip'] là có thể lấy giá trị của ip rồi.

Weitere ähnliche Inhalte

Was ist angesagt?

Lap trinh huong_doi_tuong_cpp_dhct_lesson08
Lap trinh huong_doi_tuong_cpp_dhct_lesson08Lap trinh huong_doi_tuong_cpp_dhct_lesson08
Lap trinh huong_doi_tuong_cpp_dhct_lesson08xcode_esvn
 
Thdc3 Lap Trinh C
Thdc3 Lap Trinh CThdc3 Lap Trinh C
Thdc3 Lap Trinh Cquyloc
 
Giao trinh bai tap c va c++
Giao trinh bai tap c va c++Giao trinh bai tap c va c++
Giao trinh bai tap c va c++Congdat Le
 
4 Pointer String Struct
4 Pointer String  Struct4 Pointer String  Struct
4 Pointer String StructCuong
 
Các hàm thông dụng có sẵn trong php
Các hàm thông dụng có sẵn trong phpCác hàm thông dụng có sẵn trong php
Các hàm thông dụng có sẵn trong phpSon Nguyen
 
Hàm (function)
Hàm (function)Hàm (function)
Hàm (function)Son Nguyen
 
Dữ liệu mảng (array)
Dữ liệu mảng (array)Dữ liệu mảng (array)
Dữ liệu mảng (array)Son Nguyen
 
LAP TRINH C - SESSION 2
LAP TRINH C - SESSION 2LAP TRINH C - SESSION 2
LAP TRINH C - SESSION 2pnanhvn
 

Was ist angesagt? (11)

Lap trinh huong_doi_tuong_cpp_dhct_lesson08
Lap trinh huong_doi_tuong_cpp_dhct_lesson08Lap trinh huong_doi_tuong_cpp_dhct_lesson08
Lap trinh huong_doi_tuong_cpp_dhct_lesson08
 
Thdc3 Lap Trinh C
Thdc3 Lap Trinh CThdc3 Lap Trinh C
Thdc3 Lap Trinh C
 
Giao trinh bai tap c va c++
Giao trinh bai tap c va c++Giao trinh bai tap c va c++
Giao trinh bai tap c va c++
 
4 Pointer String Struct
4 Pointer String  Struct4 Pointer String  Struct
4 Pointer String Struct
 
Các hàm thông dụng có sẵn trong php
Các hàm thông dụng có sẵn trong phpCác hàm thông dụng có sẵn trong php
Các hàm thông dụng có sẵn trong php
 
Hàm (function)
Hàm (function)Hàm (function)
Hàm (function)
 
Oubraces help
Oubraces helpOubraces help
Oubraces help
 
Dữ liệu mảng (array)
Dữ liệu mảng (array)Dữ liệu mảng (array)
Dữ liệu mảng (array)
 
Thuchanh unix moi
Thuchanh unix moiThuchanh unix moi
Thuchanh unix moi
 
LAP TRINH C - SESSION 2
LAP TRINH C - SESSION 2LAP TRINH C - SESSION 2
LAP TRINH C - SESSION 2
 
Lesson 2 lý thuyết
Lesson 2 lý thuyếtLesson 2 lý thuyết
Lesson 2 lý thuyết
 

Ähnlich wie PHP Regular expressions

Tai lieu huong_dan_ve_lap_trinh_php_7512
Tai lieu huong_dan_ve_lap_trinh_php_7512Tai lieu huong_dan_ve_lap_trinh_php_7512
Tai lieu huong_dan_ve_lap_trinh_php_7512lekytho
 
Các ví dụ về cách viết và sử dụng chương trình con
Các ví dụ về cách viết và sử dụng chương trình conCác ví dụ về cách viết và sử dụng chương trình con
Các ví dụ về cách viết và sử dụng chương trình conNhungoc Phamhai
 
Lec3. Ham.pdf
Lec3. Ham.pdfLec3. Ham.pdf
Lec3. Ham.pdfKinHongnh
 
Htaccess
HtaccessHtaccess
HtaccessLê Tú
 
Ctdl C04
Ctdl C04Ctdl C04
Ctdl C04giang
 
Hướng dẫn lập trình web với PHP - Ngày 6
Hướng dẫn lập trình web với PHP - Ngày 6Hướng dẫn lập trình web với PHP - Ngày 6
Hướng dẫn lập trình web với PHP - Ngày 6Nguyễn Tuấn Quỳnh
 
Giao trinh thiet ke web bai 4 - php
Giao trinh thiet ke web   bai 4 - phpGiao trinh thiet ke web   bai 4 - php
Giao trinh thiet ke web bai 4 - phpcashdeptrai
 
E learning lab - Tim hieu Cake PHP
E learning lab - Tim hieu Cake PHPE learning lab - Tim hieu Cake PHP
E learning lab - Tim hieu Cake PHPelearninglabvn
 
Thiet Ke Co So Du Lieu2
Thiet Ke Co So Du Lieu2Thiet Ke Co So Du Lieu2
Thiet Ke Co So Du Lieu2Vo Oanh
 
Các quy định& chuẩn trong lập trình NukeViet
Các quy định& chuẩn trong lập trình NukeVietCác quy định& chuẩn trong lập trình NukeViet
Các quy định& chuẩn trong lập trình NukeVietVu Thao
 
Bài 4 Lập trình PHP (phần 2) - Giáo trình FPT
Bài 4 Lập trình PHP (phần 2) - Giáo trình FPTBài 4 Lập trình PHP (phần 2) - Giáo trình FPT
Bài 4 Lập trình PHP (phần 2) - Giáo trình FPTMasterCode.vn
 
Phan thai trung tu dong dat hang tu he thong ban le lon nhat trung quoc
Phan thai trung   tu dong dat hang tu he thong ban le lon nhat trung quocPhan thai trung   tu dong dat hang tu he thong ban le lon nhat trung quoc
Phan thai trung tu dong dat hang tu he thong ban le lon nhat trung quocTrung Phan Thai
 
Speaker dang minh tuan javascript for php developer
Speaker dang minh tuan   javascript for php developerSpeaker dang minh tuan   javascript for php developer
Speaker dang minh tuan javascript for php developerAiTi Education
 
Javascript for php developer
Javascript for php developerJavascript for php developer
Javascript for php developerDang Tuan
 

Ähnlich wie PHP Regular expressions (20)

Kiem tra javascript
Kiem tra javascriptKiem tra javascript
Kiem tra javascript
 
Kiem tra Javasrctip
Kiem tra JavasrctipKiem tra Javasrctip
Kiem tra Javasrctip
 
Lesson 2 practice
Lesson 2 practiceLesson 2 practice
Lesson 2 practice
 
Tai lieu huong_dan_ve_lap_trinh_php_7512
Tai lieu huong_dan_ve_lap_trinh_php_7512Tai lieu huong_dan_ve_lap_trinh_php_7512
Tai lieu huong_dan_ve_lap_trinh_php_7512
 
Các ví dụ về cách viết và sử dụng chương trình con
Các ví dụ về cách viết và sử dụng chương trình conCác ví dụ về cách viết và sử dụng chương trình con
Các ví dụ về cách viết và sử dụng chương trình con
 
Lec3. Ham.pdf
Lec3. Ham.pdfLec3. Ham.pdf
Lec3. Ham.pdf
 
Htaccess
HtaccessHtaccess
Htaccess
 
Ctdl C04
Ctdl C04Ctdl C04
Ctdl C04
 
Hướng dẫn lập trình web với PHP - Ngày 6
Hướng dẫn lập trình web với PHP - Ngày 6Hướng dẫn lập trình web với PHP - Ngày 6
Hướng dẫn lập trình web với PHP - Ngày 6
 
Giao trinh thiet ke web bai 4 - php
Giao trinh thiet ke web   bai 4 - phpGiao trinh thiet ke web   bai 4 - php
Giao trinh thiet ke web bai 4 - php
 
Con trỏ trong C
Con trỏ trong CCon trỏ trong C
Con trỏ trong C
 
E learning lab - Tim hieu Cake PHP
E learning lab - Tim hieu Cake PHPE learning lab - Tim hieu Cake PHP
E learning lab - Tim hieu Cake PHP
 
Thiet Ke Co So Du Lieu2
Thiet Ke Co So Du Lieu2Thiet Ke Co So Du Lieu2
Thiet Ke Co So Du Lieu2
 
Chuong 08 tai dinh nghia
Chuong 08 tai dinh nghiaChuong 08 tai dinh nghia
Chuong 08 tai dinh nghia
 
Các quy định& chuẩn trong lập trình NukeViet
Các quy định& chuẩn trong lập trình NukeVietCác quy định& chuẩn trong lập trình NukeViet
Các quy định& chuẩn trong lập trình NukeViet
 
python3.pptx
python3.pptxpython3.pptx
python3.pptx
 
Bài 4 Lập trình PHP (phần 2) - Giáo trình FPT
Bài 4 Lập trình PHP (phần 2) - Giáo trình FPTBài 4 Lập trình PHP (phần 2) - Giáo trình FPT
Bài 4 Lập trình PHP (phần 2) - Giáo trình FPT
 
Phan thai trung tu dong dat hang tu he thong ban le lon nhat trung quoc
Phan thai trung   tu dong dat hang tu he thong ban le lon nhat trung quocPhan thai trung   tu dong dat hang tu he thong ban le lon nhat trung quoc
Phan thai trung tu dong dat hang tu he thong ban le lon nhat trung quoc
 
Speaker dang minh tuan javascript for php developer
Speaker dang minh tuan   javascript for php developerSpeaker dang minh tuan   javascript for php developer
Speaker dang minh tuan javascript for php developer
 
Javascript for php developer
Javascript for php developerJavascript for php developer
Javascript for php developer
 

PHP Regular expressions

  • 1. Regular Expressions 1. Regular expression là gì? + Biểu thức chính quy. + Hiểu nôm na là 1 chuỗi có quy tắc để mô tả những chuỗi(string) khác 2. Cú pháp cơ bản (ở đây mình chỉ trình bày và ví dụ cho ngôn ngữ php) Example: PHP Code: <?php $re = '/hello/'; // biểu thức chính quy cho một string có chuỗi “hello” ở trong đó. $str = 'hello world'; if(preg_match($re, $str)) { echo 'Yes'; } ?> Output: Yes + Ký hiệu “^” và “$”: bắt đầu và kết thúc 1 string Example: PHP Code: <?php $re = '/^hello/'; // biểu thức chính quy cho một string bắt đầu bởi chuỗi “hello” $str = 'hello world'; if(preg_match($re, $str)) { echo 'Yes'; } else { echo 'No'; } ?> Output: Yes PHP Code: <?php $re = '/hello$/'; // biểu thức chính quy cho một string kết thúc bởi chuỗi “hello” $str = 'hello world'; if(preg_match($re, $str)) { echo 'Yes'; } else { echo 'No'; } ?> Output: No + Ký hiệu: “*”, “+”, “?” $re = '/^ab*$/' ; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 0 hoặc
  • 2. nhiều b (ví dụ: a, ab, abb, abbb, …); $re = '/^ab+$/' ; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 1 hoặc nhiều b (ví dụ: ab, abb, abbb, …); $re = '/^ab?$/' : // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là b hoặc là không (ví dụ: ab hoặc a). Example: PHP Code: <?php $re = '/^ab*$/'; $str = 'abbc'; if(preg_match($re, $str)) { echo 'Yes'; } else { echo 'No'; } ?> Output: No + Sử dụng: {}: $re = '/^ab{2}$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 2 chũ b (là abb); $re = '/^ab{2,}$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là ít nhất 2 chũ b (ví dụ: abb, abbb, abbbb, …); $re = '/^ab{2,5}$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là ít nhất 2 chũ b và nhiều nhất là 5 chữ b (ví dụ: abb, abbb, abbbb, abbbbb); + Sử dụng : () và | $re = '/^a(bc)*$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 0 hoặc nhiều 'bc' (ví dụ abc, abcbc, abcbcbcbc, …) $re = '/^a(b|c)*$/'; // biểu thức chính quy cho một string bắt đầu bởi a, và kết thúc là 0 hoặc nhiều 'b' hoặc nhiều 'c' hoặc 'b' 'c' lẫn lộn :D (ví dụ abc, abbcccccccccc, abccccbbbcbc, …) + Sử dụng symbol '.': đại diện cho một ký tự đơn bất kỳ $re = '/^.{3}$/'; //Biểu thức chính quy cho một chuỗi có đúng 3 ký tự bất kỳ. PHP Code: <?php $re = '/^.{3}$/'; //Biểu thức chính quy cho một chuỗi có đúng 3 ký tự bất kỳ. $str = '&#%'; if(preg_match($re, $str)) { echo 'Yes'; } else {
  • 3. echo 'No'; } ?> Output: Yes + Sử dụng: '-': [0-9] : Một chữ số [a-zA-Z]: một ký tự A->Z, a->z [a-d] : ~ (a|b|c|d) [^a-zA-Z]: một ký tự không phải là A->Z, a->z [^0-9]: một ký tự không phải là số + Sử dụng: '' d - Chữ số bất kỳ ~ [0-9] D - Ký tự bất kỳ không phải là chữ số (ngược với d) ~ [^0-9] w - Ký tự từ a-z, A-Z, hoặc 0-9 ~ [a-zA-Z0-9] W - Ngược lại với w (nghĩa là các ký tự không thuộc các khoảng: a-z, A-Z, hoặc 0-9) ~[^a-zA-Z0-9] s - Khoảng trắng (space) S - Ký tự bất kỳ không phải là khoảng trắng. 3. Các hàm cơ bản vận dụng regular expression + preg_match : http://php.net/manual/en/function.preg-match.php int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] ) Cơ bản là để tìm kiếm 1 string có làm việc theo một $re. Ví dụ: PHP Code: <?php $re = '/^w+$/'; // một string toàn ký tự A->Z, a->z, 0->9 $str = 'quya*'; if(preg_match($re, $str)) { echo 'Yes'; } else { echo 'No'; } ?> Output: No + preg_replace: http://www.php.net/manual/en/function.preg-replace.php mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] ) Cơ bản là để tìm kiếm trong 1 string những chuỗi có cấu trúc theo $re để thay thế Ví dụ:
  • 4. PHP Code: <?php $re = '/w+$/'; $str = '*quya'; echo preg_replace($re, 'hi', $str); ?> Output: *hi + preg_split: http://php.net/manual/en/function.preg-split.php array preg_split ( string $pattern , string $subject [, int $limit = -1 [, int $flags = 0 ]] ) Ví dụ: Các bạn xem tạm ví dụ ở trong php manual nhé. Mệt rùi. Để viết ra bài này, mình đã tham khảo nhiều nguồn trên mạng, và kiến thức từ những lần sử dụng regular expressions. Có zì sai hay chưa đủ thì các bạn pm để mình bổ xung thêm. Giới thiệu Regular Expression Nâng cao I. Thêm comment vào biểu thức Regular Expression: Trong trường hợp biểu thức chính quy của bạn quá dài. Và muốn sau này người dùng sau có thể hiểu và chỉnh sửa lại (reuse), thì chúng ta cần phải ghi chú lại. hì hì. Để thêm comment vào 1 biểu thức Regular Expression hiện giờ có 2 cách thì phải. - Sử dụng cú pháp (?# nội dung ghi chú). Ví dụ: kiểm tra ngày có đúng định dạng dd/mm/yyyy không ta có parttern sau: Mã: $parttern = “/^d{2}/d{2}}/d{4}$/” //cái này ngắn quá tham khảo thôi. Sau khi thêm comment vào: Mã: $parttern = “/^d{2}(?# ngày là số nguyên 2 kí tự)/d{2}(?# Tháng là số nguyên 2 kí tự)/d{4}(?# Năm là số nguyên 4 kí tự)$/” - Cách này nhìn sáng sủa và dễ hiểu hơn: Mã: $parttern = “/^ d{2} # ngày là số nguyên 2 kí tự / # dấu phân cách “/” d{2} # Tháng là số nguyên 2 kí tự / # dấu phân cách “/” d{4} # Năm là số nguyên 4 kí tự $/x”; // Sử dụng modifier là x.
  • 5. Khi sử dụng modifier x thì khoảng trắng trong biểu thức chính quy sẽ được bỏ qua, nếu không nó sẽ được escaped (s). Điều này dễ dàng để thêm comment. Comment sẽ bắt đầu bằng dấu “#” và kết thúc tại 1 dòng mới. II. Greedy và Ungreedy: Để hiểu được phần này bạn cần xem qua ví dụ sau: Ví dụ: Mình có 1 đoạn mã html sau khi view source của 1 trang web Mã: <html> <head><title>Greedy và Ungeedy</title></head> <body> <p id=”weather”> Nội dung cần lấy nằm ở đây </p> <p> Nội dung khác </p> </body> </html> Vậy để lấy nội dung trong thẻ <p id=”weather”></p>, mình sẽ phải viết biểu thức sau: PHP Code: $parttern = “/<p id=”weather”>(.*)</p>/s”; if(preg_match($parttern, $html, $match)) { print_r($match); } Hì hì, kết quả thế nào các bạn sẽ lấy được nội dung cần lấy chứ. Mã: Array ( [0] => Nội dung cần lấy ở đây Nội dung khác [1] => Nội dung cần lấy ở đây Nội dung khác ) Như vậy, nội dung mình cần lấy vẫn chưa lấy được, tìm hiểu nguyên nhân tại sao: Xem lại $parttern của mình: $parttern = “/<p id=”weather”>(.*)</p>/s”; Mô tả parttern: bắt đầu bằng thẻ p có id=”weather”, tiếp sau là nội dung bắt kì có thể có nhiều hoặc không có kí tự nào và kết thúc là html tag </p>. Khi dùng modifier s: cho biết so khớp parttern với mọi kí tự kể cả kí tự xuống dòng, nếu không có nó kí tự xuống dòng sẽ bị loại trừ.
  • 6. - Mặc định trong so khớp mẫu thì nó sẽ lấy thẻ p có id = "weather" và nội dung bất kì bên trong đến khi gặp tag đóng </p>. Nhưng phải là tag đóng </p> cuối cùng thì nó mới dừng lại (Greedy, tiếng việt là tham lam, tham ăn gì đó) so tới cuối luôn đó mà. - Vậy làm sao để parttern hiểu rằng khi so khớp mình chỉ lấy nội dung bất kì giữa 2 tag <p id="weather">nội dung đến tag đóng </p> đầu tiên thôi. Lúc đó, mình sẽ dùng kí tự dấu hỏi "?" (Ungreedy) để thêm vào sau quantifier của parttern muốn so khớp. Hì hì Cái quantifier tham khảo lại nha, vì bài này đang hướng dẫn Advanced Regular Expression mà. - Vì vậy để lấy được nội dung chính xác với parttern của mình Mã: $parttern = '/<p id="weather">(.*)</p>/s'; thì mình chỉ cần thêm dấu hỏi sau quantifier "*" là xong. Mã: $parttern = '/<p id="weather">(.*?)</p>/s'; Chạy lại code PHP Code: $parttern = “/<p id=”weather”>(.*?)</p>/s”; if(preg_match($parttern, $html, $match)) { print_r($match); } bạn sẽ nhận được kết quả như ý Mã: Array ( [0] => Nội dung cần lấy ở đây [1] => Nội dung cần lấy ở đây ) III. Lookahead and Lookbehind Assertions (được gọi chung là lookaround) 1. Positive and Negative Lookahead: - cú pháp: positive lookahead (?=), negative lookahead (?!) - Bạn có thể xem qua ví dụ để hiểu rõ hơn: Mã: $parttern = "/hellos*(?=world)/"; - Ý nghĩa: đầu tiên mẫu sẽ so khớp bắt đầu bằng hello, tiếp theo sẽ là có thể có nhiều hoặc không có khoảng trắng, và cuối cùng theo sau nó có phải là world không. Các bạn thấy đó, $parttern để thực hiện mục đích này không thật sự hữu dụng vì sao, chúng ta không cần biết lookahead thì vẫn thực hiện được với:
  • 7. Mã: $parttern = "/hellos*world/"; điều này là sai lầm. hì hì. Nếu bạn chỉ muốn tìm xem chuỗi có đúng như vậy không, chỉ nhận về kết quả true hoặc false là có thể bạn cho là sử dụng lookahead lúc này là không có khả dụng. Tuy nhiên, nếu đi sâu vào hơn, bạn sử dụng kết quả trả về của code: PHP Code: $chuoi = "hello world"; $parttern = "/hellos*(?=world)/"; $parttern1 = "/hellos*world/"; if(preg_match($parttern, $chuoi)) { echo "valid"; } // tương đương với if(preg_match($parttern1, $chuoi)) { echo "valid"; } Nhưng nếu bạn muốn sử dụng kết quả trả về. Ở đây mình lấy ví dụ của bài đầu Greedy và Ungreedy Mã html sau khi viewsource 1 trang web PHP Code: //tạo biến $html giữ nội dung trang web. $html = '<html> <head><title>Greedy và Ungeedy</title></head> <body> <p id=”weather”> Nội dung cần lấy nằm ở đây </p> <p> Nội dung khác </p> </body> </html>'; và nội dung trả về sau khi thực hiện đoạn code là gì nhỉ các bạn PHP Code: $parttern = “/<p id=”weather”>(.*?)</p>/s”; if(preg_match($parttern, $html, $match)) { print_r($match[0]); }
  • 8. kết quả: Mã: Nội dung cần lấy ở đây Có phải nội dung bạn cần lấy là nội dung nằm giữa thẻ <p id="weather"> và thẻ đóng </p>. Nhìn kết quả xuất ra khi dùng print_r($match[0]). các bạn cho rằng là đúng. Mình cũng thấy đúng mà, nhưng khi bạn view source thử xem, kết quả thế nào nhỉ. không tồi, hihi kết quả viewsource Mã: <p id="weather"> Nội dung cần lấy nằm ở đây </p> Kết quả là nó lấy luôn thẻ p đóng và mở àh các bạn, vậy làm sao mẫu so khớp vẫn kiểm tra đúng mà kết quả trả về, mình sẽ loại bỏ cái tag p đóng và mở àh nhỉ. --> lookahead and lookbehind was born. (rồi thấy được công dụng nha các bạn). - Sửa lại cấu trúc $parttern PHP Code: $parttern_old = '/<p id="weather">(.*?)</p>/s'; $parttern_new = '/(?<=<p id="weather">)(.*?)(?=</p>)/s'; - Giải thích $parttern_new: lấy nội dung bất kì mà theo trước nó là tab mở <p id="weather"> và theo sau nó là tag đóng </p> (Không bao gồm tag mở và đóng nha bạn). 2. Positive and Negative Lookbehind: - Cú pháp: positive lookbehind (?<=), negative lookbehind. - Mình chỉ đưa ra ví dụ và nêu ý nghĩa, giống ở trên các bạn tìm hiểu nha. (?<!) IV. Conditional (If-Then-Else) Patterns - Regular Expression cung cấp cho chúng ta chức năng kiểm tra điều kiện. - Cú pháp: (?(condition)true-pattern|false-pattern) hoặc (?(condition)true-pattern) - Giải thích: nếu condition đúng thì so khớp true-parttern, ngược lại so khớp với false- parttern. ví dụ: PHP Code: // nếu bắt đầu với h thì , so khớp he // ngược lại so khớp với she $pattern = '/^(?(?=h)he|she)/'; preg_match($pattern, 'he'); // true preg_match($pattern, 'she'); // true preg_match($pattern, 'shoes'); // false
  • 9. - chú ý: điều kiện condition có thể là 1 con số. Trong trường hợp này, nó sẽ tham chiếu đến capture subpartter ở phía trước nó. ví dụ: PHP Code: // parttern (a)?b(?(1)c|d) khớp với bd và abc. nhưng nó khô ng khớp với bc $parttern = "(a)?b(?(1)c|d)"; preg_match($pattern, 'bd'); // true preg_match($pattern, 'abc'); // true preg_match($pattern, 'bc'); // false - Phân tích: $pattern = "(a)?b(?(1)c|d)"; bắt đầu bằng 1 subparttern (a) hoặc không có theo sau là b và cuối là 1 parttern if-else condition (?(1)c|d). - Giải thích: PHP Code: $parttern = "(a)?b(?(1)c|d)"; preg_match($pattern, 'bd'); /* so khớp parttern với chuỗi 'bd'. ta thấy, bắt đầu bằng b vì subpartter a có thể có hoặc khô ng, tiếp đến là condition số 1 sẽ tham chiếu tới subparrtern a ở phía trước, vì không có a nên (?(1)c|d) sẽ trả về kết quả false, nên biểu thức tiếp tục so khớp với d. và kết thúc chuỗi là d nên thỏa => kết quả true */ V. Non-capturing Subpatterns - Cú pháp: (?:subparttern) - Subparttern kèm theo dấu ngoặc đơn, được lưu giữ vào 1 mảng để chúng ta có thể sử dụng chúng sau này khi cần thiết. Nhưng đối với những biểu thức chúng ta chỉ muốn giữ những giá trị của subparttern cần thiết, và không lưu lại những giá trị của parttern khác, chúng ta sẽ sử dụng cú pháp ở trên (?:subparttern) (gọi là non - capturing subparttern). - Các bạn xem ví dụ sau để dễ hiểu hơn: PHP Code: preg_match('/(f.*)(b.*)/', 'Hello foobar', $matches); echo "f* => " . $matches[1]; // prints 'f* => foo' echo "b* => " . $matches[2]; // prints 'b* => bar' - Thay đổi 1 chút bằng cách thêm 1 subparttern (H*) ở phía trước PHP Code:
  • 10. preg_match('/(H.*) (f.*)(b.*)/', 'Hello foobar', $matches); echo "f* => " . $matches[1]; // prints 'f* => Hello' echo "b* => " . $matches[2]; // prints 'b* => foo' - Mảng $matches lúc này đã thay đổi, giá trị của subparttern (H*) được giữ lại và tương ứng với chỉ số của mảng $matches là $matches[1]. Chúng ta thực sự không muốn giữ lại giá trị của subparttern này chúng ta chỉ cần làm cho nó thành non - capturing subparttern bằng cách: PHP Code: preg_match('/(?:H.*) (f.*)(b.*)/', 'Hello foobar', $matches ); echo "f* => " . $matches[1]; // prints 'f* => foo' echo "b* => " . $matches[2]; // prints 'b* => bar' VI. Named Subpatterns - Cú pháp: (?P<named_subparttern>subpattern) - sau khi lấy giá trị của subparttern gán vào biến $matches, nếu chúng ta muốn truy xuất đến các giá trị của subpattern bằng tên thì chúng ta sử dụng cú pháp trên. Việc sử dụng tên của subpattern sẽ dễ dàng cho chúng ta quản lý và truy xuất hơn. - Các bạn xem ví dụ sau: PHP Code: $html=' ip: 192.168.1.1 name: truong-pc ip: 192.168.1.2 name: thuy '; $patternip = '/(?P<ip>(?<=ip:)s*d+.d+.d+.d+)/'; preg_match_all($patternip,$html, $matches); echo "<pre>"; print_r($matches); echo "</pre>"; - Mảng $matches sẽ có giá trị Mã: Array ( [0] => Array ( [0] => 192.168.1.1 [1] => 192.168.1.2
  • 11. ) [ip] => Array ( [0] => 192.168.1.1 [1] => 192.168.1.2 ) [1] => Array ( [0] => 192.168.1.1 [1] => 192.168.1.2 ) ) - Khi đó chúng ta muốn lấy giá trị của subparttern ip chúng ta chỉ cần truy cập $matches['ip'] là có thể lấy giá trị của ip rồi.