Regular Expression (RegEx) trong Python

Thứ tư - 12/07/2023 09:52

Regex trong Python là gì? Cách dùng Regex Python như thế nào? Hãy cùng Quantrimang.com tìm hiểu nhé!

Python là ngôn ngữ lập trình phổ biến trong lĩnh vực phát triển ứng dụng, web, chương trình cho mobile và nhiều hơn thế nữa. Học và sử dụng Python không khó. Về cơ bản, bạn cần biết Python là gì cùng các hàm thông dụng của nó. Ở bài viết này, chúng ta sẽ tìm hiểu về Regular Expression (RegEx) với module re cùng ví dụ minh họa cụ thể.

Một biểu thức chính quy Regular Expressions (RegEx) trong Python là một chuỗi ký tự đặc biệt dùng mẫu tìm kiếm để tìm một chuỗi hoặc một nhóm chuỗi. Nó có thể phát hiện sự hiện diện hoặc vắng mặt của một văn bản bằng cách kết hợp nó với một mẫu cụ thể, đồng thời, có thể tách một mẫu thành một hoặc nhiều mẫu phụ. Python cung cấp mô đun re, hỗ trợ sử dụng regex trong ngôn ngữ lập trình này. Chức năng cơ bản của nó là cung cấp tìm kiếm, tại nơi nó nhận biểu thức thông thường và một chuỗi. Sau đó, nó trả về kết quả trùng khớp đầu tiên hoặc thông báo lỗi.

Ví dụ:

^a...s$

Đoạn code trên xác định quy tắc RegEx: bất kỳ chuỗi nào có năm chữ cái, bắt đầu bằng a và kết thúc bằng s.

Biểu thức Chuỗi ví dụ Mô tả
^a...s$ abs Không phù hợp vì chỉ có 3 ký tự
alias Phù hợp
abyss Phù hợp
Alias Không phù hợp vì chữ cái đầu viết hoa A
An abacus Không phù hợp vì chữ cái đầu viết hoa A và nhiều hơn 5 ký tự

Regular Expression trong Python được thể hiện qua module re, nên việc đầu tiên khi các bạn muốn sử dụng Regular Expression thì cần phải import module re vào chương trình. Thử với ví dụ trên:

import re

pattern = '^a...s$'
test_string = 'abyss'
result = re.match(pattern, test_string)

if result:
  print("Tim kiem thanh cong.")
else:
  print("Tim kiem khong thanh cong.")

Ở đây chúng ta vừa sử dụng hàm re.match() để tìm kiếm test_string tương ứng với pattern. Phương thức trả về đối tượng tương ứng nếu tìm kiếm thành công, trả về None nếu không tìm thấy.

Hầu như ngôn ngữ nào cũng hỗ trợ Regular Expression, kể đến như JavaScript, C#, Java, PHP, Ruby, SQL, Oracle, Perl... nhưng được sử dụng phổ biến nhất trong Unix/Linux.

Còn một số hàm khác có trong mudule re để hoạt động với RegEx. Trước khi đi sâu vào các hàm này, hãy tìm hiểu kĩ hơn về biểu thức chính quy RegEx.

Cú pháp pattern sử dụng trong RegEx Python

Pattern ta hiểu 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. Để chỉ định biểu thức chính quy, ta sử dụng các ký tự đặc biệt, bao gồm:

[] . ^ $ * + ? {} () \ |

Trong ví dụ trên là ký tự ^ và $.

Dấu ngoặc vuông []

Dấu ngoặc vuông sử dụng để thể hiện tập các ký tự bạn muốn khớp.

Biểu thức Chuỗi ví dụ Mô tả
[abc] a Khớp với ký tự a
ac Khớp với ký tự a hoặc c
Hey Jude Không khớp

Ở đây, [abc] sẽ khớp nếu chuỗi bạn truyền có chứa bất kỳ ký tự ab hoặc c nào.

Bạn cũng có thể chỉ định một phạm vi các ký tự bằng cách sử dụng - bên trong dấu ngoặc vuông.

  • [a-e] tương tự với [abcde].
  • [1-4] tương tự với [1234].
  • [0-39] tương tự với [01239].

Nếu ký tự đầu tiên của tập hợp là ^ thì tất cả các ký tự không được định nghĩa trong tập hợp sẽ được so khớp.

  • [^abc] nghĩa là khớp với các chuỗi không có ký tự ab hay c.
  • [^0-9] nghĩa là khớp với các chuỗi không có ký tự chữ số nào.

Các ký tự đặc biệt trong [] sẽ được coi như ký tự thông thường.

  • [(+)] khớp với bất kỳ chuỗi nào có ký tự (+ hoặc ).

Dấu chấm .

Dấu chấm khớp với bất kỳ ký tự đơn thông thường nào ngoại trừ ký tự tạo dòng mới '\n'.

Biểu thức Chuỗi ví dụ Mô tả
.. a Không khớp vì chỉ có một ký tự
ac Khớp vì có hai ký tự
acd Khớp vì có hai ký tự trở lên

Dấu mũ ^

Biểu tượng dấu mũ ^ được sử dụng để khớp ký tự đứng đầu một chuỗi.

Biểu thức Chuỗi ví dụ Mô tả
^a a Khớp vì bắt đầu bằng a
abc Khớp vì bắt đầu bằng a
bac Không khớp vì a không nằm ở đầu tiên
^ab abc Khớp vì bắt đầu bằng ab
acb Không khớp, bắt đầu bằng a nhưng ký tự tiếp theo không phải b

Biểu tượng Dollar $

Biểu tượng Dollar $ được sử dụng để khớp ký tự kết thúc một chuỗi.

Biểu thức Chuỗi ví dụ Mô tả
a$ a Khớp vì kết thúc bằng a
formula Khớp vì kết thúc bằng a
cab Không khớp vì a không nằm ở vị trí cuối cùng

Dấu hoa thị *

Biểu tượng dấu hoa thị * có thể khớp với chuỗi có hoặc không có ký tự được định nghĩa trước nó. Ký tự này có thể được lặp lại nhiều lần mà không bị giới hạn số lượng.

Biểu thức Chuỗi ví dụ Mô tả
ma*n mn Khớp vì ký tự trước * có thể không xuất hiện
man Khớp vì có xuất hiện đầy đủ các ký tự
maaaan Khớp vì ký tự trước * có thể xuất hiện nhiều lần
main Không khớp vì không giống pattern, n không nằm kế a
woman Khớp vì có xuất hiện đầy đủ các ký tự

Dấu cộng +

Biểu tượng dấu cộng + có thể khớp với chuỗi có một hoặc nhiều ký tự được định nghĩa trước nó. Ký tự này có thể được lặp lại nhiều lần mà không bị giới hạn số lượng.

Biểu thức Chuỗi ví dụ Mô tả
ma+n mn Không khớp vì ký tự a trước + không xuất hiện
man Khớp vì có xuất hiện đầy đủ các ký tự
maaaan Khớp vì ký tự trước + có thể xuất hiện nhiều lần
main Không khớp vì không giống pattern, n không nằm kế a
woman Khớp vì có xuất hiện đầy đủ các ký tự

Dấu chấm hỏi ?

Biểu tượng dấu chấm hỏi có thể khớp với chuỗi có hoặc không có ký tự được định nghĩa trước nó. Ký tự này không thể được lặp lại nhiều lần, chỉ giới hạn số lượng với một lần xuất hiện.

Biểu thức Chuỗi ví dụ Mô tả
ma?n mn Khớp vì ký tự trước ? có thể không xuất hiện
man Khớp vì có xuất hiện đầy đủ các ký tự
maaaan Không khớp vì ký tự trước ? chỉ có thể xuất hiện 1 lần
main Không khớp vì không giống pattern, n không nằm kế a
woman Khớp vì có xuất hiện đầy đủ các ký tự

Dấu ngoặc nhọn {}

Dấu ngoặc nhọn sử dụng theo công thức tổng quát: {n,m}, đại diện cho việc ký tự đằng trước nó có thể xuất hiện tối thiểu n lần vào tối đa m lần. n và m là số nguyên dương và n <= m.

  • Nếu bỏ trống n, giá trị này mặc định bằng 0.
  • Nếu bỏ trống m, giá trị này mặc định là vô hạn.
Biểu thức Chuỗi ví dụ Mô tả
a{2,3} abc dat Không khớp vì không thỏa mãn điều kiện
abc daat Khớp vì có xuất hiện 2 ký tự a (daat)
aabc daaat Khớp vì có xuất hiện 2 và 3 ký tự a (aabc và daaat)
aabc daaaat Khớp vì có xuất hiện 2 và 3 ký tự a (aabc và daaaat)

Hãy thử một ví dụ nữa: RegEx [0-9] {2, 4} này khớp với chuỗi có tối thiểu 2 chữ số và tối đa không quá 4 chữ số.

Biểu thức Chuỗi ví dụ Mô tả
[0-9]{2,4} ab123csde Khớp vì thỏa mãn điều kiện: ab123csde
12 and 345673 Khớp vì thỏa mãn điều kiện: 12 và 345673
1 and 2 Không khớp vì chuỗi chỉ có 1 chữ số

Dấu sổ dọc |

Biểu tượng dấu sổ dọc | này có thể khớp với chuỗi tồn tại 1 trong 2 ký tự được định nghĩa trước và sau nó.

Biểu thức Chuỗi ví dụ Mô tả
a|b cde Không khớp vì ab đều không xuất hiện
ade Khớp vì thỏa mãn điều kiện, có a xuất hiện: ade
acdbea Khớp vì thỏa mãn điều kiện, a và b đều xuất hiện: acdbea

Ở đây, a|b khớp với bất kỳ chuỗi nào chứa a hoặc b.

Dấu ngoặc đơn ()

Dấu ngoặc đơn () được sử dụng để gom nhóm các pattern lại với nhau, chuỗi sẽ khớp với biểu thức chính quy bên trong dấu ngoặc này.

Ví dụ: (a|b|c)xz khớp với bất kỳ chuỗi nào có a hoặc b hoặc c đứng trước xz.

Biểu thức Chuỗi ví dụ Mô tả
(a|b|c)xz ab xz Không khớp vì a hay b có đứng trước nhưng không liền với xz
abxz Khớp vì thỏa mãn điều kiện, có b xuất hiện sát trước xzabxz
axz cabxz Khớp vì thỏa mãn điều kiện, cả a và b đều xuất hiện sát trước xzaxz cabxz

Dấu gạch chéo ngược \

Dấu gạch chéo ngược được sử dụng để thoát các ký tự đặc biệt, nghĩa là khi đứng trước một kí tự đặc biệt, \ sẽ biến kí tự này thành một kí tự thường, bạn có thể tìm kiếm kí tự đặc biệt này trong chuỗi như các kí tự thường khác.

Ví dụ: \$a sẽ khớp với chuỗi chứa ký tự $ đứng trước a. Ở đây, biểu tượng Dollar $ không sử dụng để khớp một chuỗi kết thúc bằng ký tự đi cùng nó như trong công cụ RegEx, $ chỉ là ký tự bình thường.

Tuy nhiên, một dấu gạch chéo ngược cũng sẽ biến một kí tự thường liền kế phía sau thành một kí tự đặc biệt.

Ví dụ, trường hợp ký tự b không có dấu gạch chéo ngược sẽ khớp với các ký tự b in thường, nhưng khi nó có thêm dấu gạch chéo ngược, \b thì nó trở thành kí tự đặc biệt, không khớp với bất kì ký tự nào nữa.

Một số pattern đi với \

1. \A - Khớp với các ký tự theo sau nó nằm ở đầu chuỗi.

Biểu thức Chuỗi ví dụ Mô tả
\Athe the sun Khớp vì the nằm ở đầu chuỗi
In the sun Không khớp vì the không nằm ở đầu chuỗi

2. \b - Khớp với các ký tự được chỉ định nằm ở đầu hoặc cuối của từ.

Biểu thức Chuỗi ví dụ Mô tả
\bfoo football Khớp vì thỏa mãn điều kiện, foo nằm ở đầu chuỗi
a football Khớp vì thỏa mãn điều kiện, foo nằm ở đầu từ thứ 2 trong chuỗi
afootball Không khớp vì foo nằm ở giữa từ trong chuỗi.
foo\b the foo Khớp vì thỏa mãn điều kiện, foo nằm ở cuối chuỗi
the afoo test Khớp vì thỏa mãn điều kiện, foo nằm ở cuối từ thứ 2 trong chuỗi
the afootest Không khớp vì foo nằm ở giữa từ trong chuỗi.

3. \B - Trái ngược với \b, khớp với các ký tự được chỉ định không nằm ở đầu hoặc cuối của từ.

Biểu thức Chuỗi ví dụ Mô tả
\bfoo football Không khớp vì foo nằm ở đầu chuỗi
a football Không khớp vì foo nằm ở đầu từ thứ 2 trong chuỗi
afootball Khớp vì foo nằm ở giữa từ trong chuỗi.
foo\b the foo Không khớp vì foo nằm ở cuối chuỗi
the afoo test Không khớp vì foo nằm ở cuối từ thứ 2 trong chuỗi
the afootest Khớp vì foo nằm ở giữa từ trong chuỗi.

4. \d - Khớp với các ký tự là chữ số, tương đương với [0-9].

Biểu thức Chuỗi ví dụ Mô tả
\d 12abc3 Khớp vì thỏa mãn điều kiện: 12abc3
Python Không khớp vì không có số nguyên nào xuất hiện

5. \D - Khớp với các ký tự không phải số, tương đương với [^0-9].

Biểu thức Chuỗi ví dụ Mô tả
\D 1ab34"50 Khớp vì thỏa mãn điều kiện: 1ab34"50
1345 Không khớp vì chuỗi toàn số nguyên xuất hiện

6. \s - Khớp với bất kỳ ký tự khoảng trắng nào, tương đương với [ \t\n\r\f\v].

Biểu thức Chuỗi ví dụ Mô tả
\s Python RegEx Khớp vì chuỗi có khoảng trắng
PythonRegEx Không khớp vì chuỗi không có khoảng trắng

7. \S - Khớp với bất kỳ ký tự nào không phải khoảng trắng, tương đương với [^ \t\n\r\f\v].

Biểu thức Chuỗi ví dụ Mô tả
\S a b Khớp vì chuỗi có ký tự a b
  Không khớp vì chuỗi toàn bộ là khoảng trắng

8. \w - Khớp với bất kỳ ký tự chữ cái và chữ số nào, tương đương với [a-zA-Z0-9_].

Lưu ý: Dấu gạch dưới _ cũng được coi là một ký tự chữ cái và chữ số.

Biểu thức Chuỗi ví dụ Mô tả
\w 12&": ;c Khớp vì chuỗi có ký tự chữ và số 12&": ;c
%"> ! Không khớp vì chuỗi không có ký tự chữ và số

9. \W - Khớp với bất kỳ ký tự nào không phải là chữ cái và chữ số, tương đương với [^a-zA-Z0-9_].

Biểu thức Chuỗi ví dụ Mô tả
\w 1a2%c Khớp vì chuỗi có ký tự không phải chữ và số 1a2%c
Python Không khớp vì chuỗi chỉ có ký tự chữ cái

Lưu ý: Dấu gạch dưới _ cũng được coi là một ký tự chữ cái và chữ số.

Tips: Để xây dựng các biểu thức chính quy RegEx, bạn có thể sử dụng công cụ kiểm tra RegEx như regex101. Công cụ này không chỉ tạo các biểu thức chính quy mà còn giúp bạn tìm hiểu nó kỹ hơn.

Bây giờ thì bạn đã hiểu những điều cơ bản về RegEx, hãy cùng thảo luận về cách sử dụng RegEx trong code Python.

Regular Expression trong Python

Regular Expression trong Python được thể hiện qua module re, nên việc đầu tiên khi các bạn muốn sử dụng regular expression thì cần phải import module re vào chương trình.

import re

Module này có rất nhiều các phương thức, hàm và hằng để làm việc với RegEx. Quantrimang.com sẽ liệt kê một số hay được sử dụng kèm theo ví dụ để bạn dễ hình dung và nắm bắt.

re.findall()

Phương thức re.findall() trả về một danh sách các chuỗi chứa tất cả các kết quả khớp với pattern đưa ra.

Cú pháp:

findall(partern, string)

Trong đó:

  • pattern là RegEx.
  • string là chuỗi cần so khớp.

Ví dụ: Trích xuất các số từ chuỗi cho trước sau: "hello 12 hi 89. Howdy 34"

import re

string = 'hello 12 hi 89. Howdy 34'
pattern = '\d+'

result = re.findall(pattern, string) 
print(result)

Kết quả trả về:

['12', '89', '34']

re.split()

Phương thức re.split() dùng biểu thức chính quy để ngắt chuỗi thành các chuỗi con và trả về danh sách các chuỗi con này.

Cú pháp:

re.split(pattern, string, maxsplit)

Trong đó:

  • pattern là RegEx.
  • string là chuỗi cần so khớp.
  • maxsplit (số nguyên) là số chuỗi tối đa sẽ được ngắt. Nếu để trống thì Python sẽ so khớp và cắt tất cả các chuỗi đạt điều kiện.

Ví dụ: Ngắt tại vị trí có ký tự khoảng trắng:

import re

string = 'The rain in Vietnam.'
pattern = '\s'

result = re.split(pattern, string) 
print(result)

Kết quả trả về:

['The', 'rain', 'in', 'Vietnam.']

Ví dụ: Ngắt chuỗi ở ký tự khoảng trắng đầu tiên:

import re

string = 'The rain in Vietnam.'
pattern = '\s'

result = re.split(pattern, string, 1) 
print(result)

Kết quả:

['The', 'rain in Vietnam.']

Nếu không tìm thấy pattern, re.split() trả về danh sách chứa chuỗi rỗng.

re.sub()

Đây là một trong những phương thức quan trọng nhất sử dụng với Regular Expression

Re.sub() sẽ thay thế tất cả các kết quả khớp với pattern trong chuỗi bằng một nội dung khác được truyền vào và trả về chuỗi đã được sửa đổi.

Cú pháp:

re.sub(pattern, replace, string, count)

Trong đó:

  • pattern là RegEx.
  • replace là nội dung thay thế cho chuỗi kết quả khớp với pattern.
  • string là chuỗi cần so khớp.
  • count (số nguyên) là số lần thay thế. Nếu để trống thì Python sẽ coi giá trị này bằng 0, so khớp và thay thế tất cả các chuỗi đạt điều kiện.

Ví dụ: Code chương trình xóa tất cả các khoảng trắng

import re

# chuỗi nhiều dòng
string = 'abc 12\
de 23 \n f45 6'

# so khớp các ký tự khoảng trắng
pattern = '\s+'

# chuỗi rỗng
replace = ''

new_string = re.sub(pattern, replace, string) 
print(new_string)

Kết quả trả về:

abc12de23f456

Nếu không tìm thấy kết quả phù hợp với pattern, re.sub() sẽ trả về chuỗi rỗng.

Ví dụ: Code chương trình xóa 2 khoảng trắng đầu tiên

import re

# chuỗi nhiều dòng
string = 'abc 12\
de 23 \n f45 6 \n quantrimang website'

# so khớp các ký tự khoảng trắng
pattern = '\s+'
replace = ''

new_string = re.sub(r'\s+', replace, string, 2) 
print(new_string)

Output trả về:

abc12de23 
 f45 6 
 quantrimang website

re.subn()

Phương thức re.subn() sử dụng tương tự như re.sub() ở trên, nhưng kết quả trả về bao gồm một tuple chứa hai giá trị: chuỗi mới sau khi được thay thế và số lần thay thế đã thực hiện.

import re

# chuỗi nhiều dòng
string = 'abc 12\
de 23 \n f45 6 \n quantrimang website'

# so khớp các ký tự khoảng trắng
pattern = '\s+'

# chuỗi rỗng
replace = ''

new_string = re.subn(pattern, replace, string) 
print(new_string)

Kết quả trả về:

('abc12de23f456quantrimangwebsite', 6)

re.search()

Phương thức re.search() sử dụng để tìm kiếm chuỗi phù hợp với pattern RegEx. Nếu tìm kiếm thành công, re.search() trả về đối tượng khớp, nếu không, nó trả về None.

Cú pháp:

search(pattern, string)

Trong đó:

  • pattern là RegEx.
  • string là chuỗi cần so khớp.
import re

string = "Quantrimang.com la website ban co the hoc Python"

# Kiem tra xem 'Quantrimang' co nam o dau chuoi khong
match = re.search('\AQuantrimang', string)

if match: # nếu tồn tại chuỗi khớp
  print("Tim thay 'Quantrimang' nam o dau chuoi") # in ra thong bao nay
else:
  print("'Quantrimang' khong nam o dau chuoi") # khong thi in ra thong bao nay

Kết quả trả về:

Tim thay 'Quantrimang' nam o dau chuoi

Ở ví dụ này, match chứa đối tượng phù hợp khớp với pattern.

Đối tượng match

Một số phương thức và thuộc tính thường được sử dụng với đối tượng match.

match.group()

Phương thức group() trả về những phần của chuỗi khớp với pattern.

import re

string = '39801 356, 2102 1111'

pattern = '(\d{3}) (\d{2})'

match = re.search(pattern, string)

if match: #nếu tồn tại chuỗi khớp
  print(match.group()) # in ra kết quả
else:
  print("Không khớp") # Không thì hiện thông báo

# Output: 801 35

Ở đây, biến match chứa đối tượng match.

Ta có pattern là (\d{3}) (\d{2}) chia làm hai nhóm nhỏ (\d{3}) và (\d{2}). Bạn có thể nhận được một phần của chuỗi tương ứng với các nhóm con trong ngoặc đơn này như sau:

>>> match.group(1)
'801'

>>> match.group(2)
'35'

>>> match.group(1, 2)
('801', '35')

>>> match.groups()
('801', '35')

match.start(), match.end() và match.span()

Hàm start() trả về chỉ mục bắt đầu của chuỗi con phù hợp. Tương tự, end() trả về chỉ mục kết thúc của chuỗi con phù hợp.

>>> match.start()
2
>>> match.end()
8

Hàm span() trả về tuple chứa chỉ mục bắt đầu và kết thúc của phần chuỗi phù hợp.

>>> match.span()
(2, 8)

match.re và match.string

Thuộc tính re của đối tượng match sẽ trả về một biểu thức chính quy. Tương tự, thuộc tính string trả về chuỗi đã được truyền trong đoạn code.

>>> match.re
re.compile('(\\d{3}) (\\d{2})')
>>> match.string
'39801 356, 2102 1111'

Trên đây là tất cả các phương thức thường được sử dụng nhất trong module re.

Sử dụng tiền tố r trước RegEx

Khi tiền tố r hoặc R được sử dụng trước một biểu thức chính quy đại diện cho việc chuỗi tiếp sau nó chỉ là những ký tự bình thường.

Ví dụ: '\n' là một dòng mới newline, còn r'\n' có nghĩa là chuỗi bao gồm hai ký tự: dấu gạch chéo ngược \ và n.

Dấu gạch chéo ngược \ được sử dụng để thoát các ký tự như đã nói ở trên. Tuy nhiên, sử dụng tiền tố r trước \ thì nó chỉ là một ký tự bình thường.

import re

string = '\n and \r are escape sequences.'

result = re.findall(r'[\n\r]', string) 
print(result)

# Output: ['\n', '\r']

Nguồn tin: Quantrimang.com

Tổng số điểm của bài viết là: 0 trong 0 đánh giá

  Ý kiến bạn đọc

THỐNG KÊ TRUY CẬP
  • Đang truy cập28
  • Máy chủ tìm kiếm1
  • Khách viếng thăm27
  • Hôm nay9,466
  • Tháng hiện tại75,086
  • Tổng lượt truy cập8,860,212
QUẢNG CÁO
Phan Thanh Phú
Quảng cáo 2
Liên kết site
Đăng nhập Thành viên
Hãy đăng nhập thành viên để trải nghiệm đầy đủ các tiện ích trên site
Thăm dò ý kiến

Bạn thấy Website cần cải tiến những gì?

Lịch Âm dương
Máy tính
Bạn đã không sử dụng Site, Bấm vào đây để duy trì trạng thái đăng nhập. Thời gian chờ: 60 giây