Sitelet https://www.datacamp.com/vi/tutorial/python-regular-expression-tutorial
Chuyển đến nội dung chính

Hướng dẫn Biểu thức Chính quy trong Python

Khám phá sức mạnh của biểu thức chính quy với hướng dẫn này. Bạn sẽ làm việc với thư viện re, xử lý khớp mẫu, tìm hiểu khớp tham lam và không tham lam, và còn nhiều hơn nữa!
Đã cập nhật 5 thg 10, 2026  · 14 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity

Chạy và chỉnh sửa mã từ hướng dẫn trực tuyến này

Chạy mã
banner

Biểu thức chính quy, thường được viết tắt là regex, là một chuỗi ký tự dùng để kiểm tra xem một mẫu có tồn tại trong văn bản (chuỗi) đã cho hay không. Nếu bạn từng dùng công cụ tìm kiếm, tính năng tìm và thay thế của trình soạn thảo văn bản hay trình chỉnh sửa mã — bạn đã nhìn thấy regex hoạt động. Chúng được dùng phía máy chủ để xác thực định dạng email hoặc mật khẩu khi đăng ký, dùng để phân tích các tệp dữ liệu văn bản nhằm tìm, thay thế hoặc xóa một số chuỗi nhất định, v.v. Regex hỗ trợ thao tác dữ liệu văn bản, vốn thường là điều kiện tiên quyết cho các dự án khoa học dữ liệu liên quan đến khai phá văn bản.

Hướng dẫn này sẽ dẫn bạn qua những khái niệm quan trọng của regex với Python. Bạn sẽ bắt đầu bằng nhập re — thư viện Python hỗ trợ regex. Sau đó, bạn sẽ thấy cách dùng ký tự cơ bản/thông thường để khớp mẫu, tiếp theo là ký tự đại diện hoặc ký tự đặc biệt. Kế đó, bạn sẽ học cách dùng lặp trong regex của mình. Bạn cũng sẽ học cách tạo nhóm và nhóm có tên trong quá trình tìm kiếm để dễ truy cập kết quả khớp. Tiếp theo, bạn sẽ làm quen với khái niệm khớp tham lam so với không tham lam.

Nghe có vẻ nhiều, vì vậy đã có một bảng tóm tắt tiện dụng kèm theo để giúp bạn ghi nhớ những gì đã xem với các định nghĩa ngắn gọn. Nhớ xem nhé!

Hướng dẫn này cũng đề cập đến một số hàm hữu ích do thư viện re cung cấp, như: compile(), search(), findall(), sub() để tìm và thay thế, split(), và một vài hàm khác. Bạn cũng sẽ tìm hiểu về cờ biên dịch có thể dùng để làm regex của bạn hiệu quả hơn.

Cuối cùng, có một nghiên cứu tình huống — nơi bạn có thể áp dụng những gì đã học! Bắt đầu regex thôi...

Biểu thức chính quy trong Python

Trong Python, regex được hỗ trợ bởi mô-đun re. Điều đó có nghĩa là nếu bạn muốn bắt đầu sử dụng trong các tập lệnh Python, bạn phải import mô-đun này bằng import:

import re

Thư viện re trong Python cung cấp nhiều hàm đáng để thành thạo. Bạn sẽ thấy một số trong chúng ở gần hơn trong hướng dẫn này.

Mẫu cơ bản: Ký tự thông thường

Bạn có thể xử lý dễ dàng nhiều mẫu cơ bản trong Python bằng các ký tự thông thường. Ký tự thông thường là regex đơn giản nhất. Chúng khớp chính xác với bản thân và không có ý nghĩa đặc biệt trong cú pháp regex.

Ví dụ: 'A', 'a', 'X', '5'.

Các ký tự thông thường có thể dùng để thực hiện khớp chính xác đơn giản:

pattern = r"Cookie"
sequence = "Cookie"
if re.match(pattern, sequence):
    print("Match!")
else: print("Not a match!")
Match!

Hầu hết các chữ cái và ký tự sẽ tự khớp, như bạn đã thấy trong ví dụ.

Hàm match() trả về một đối tượng khớp nếu văn bản khớp mẫu. Nếu không, nó trả về None. Mô-đun re cũng chứa một số hàm khác, và bạn sẽ học một vài trong số đó ở phần sau của hướng dẫn.

Hiện tại, hãy tập trung vào các ký tự thông thường!

Bạn có để ý r ở đầu mẫu Cookie không?
Điều này được gọi là raw string literal (chuỗi thô). Nó thay đổi cách diễn giải chuỗi. Những literal như vậy được lưu đúng như hiển thị.

Ví dụ, \ chỉ là một dấu gạch chéo ngược khi có tiền tố r thay vì bị hiểu là chuỗi thoát. Bạn sẽ thấy điều này có ý nghĩa gì với các ký tự đặc biệt. Đôi khi cú pháp bao gồm các ký tự có tiền tố gạch chéo ngược, và để ngăn chúng bị hiểu là chuỗi thoát, bạn dùng tiền tố chuỗi thô r.

MẸO: Bạn thực ra không cần dùng trong ví dụ này; tuy nhiên, nên dùng để nhất quán.

Ký tự đại diện: Ký tự đặc biệt

Ký tự đặc biệt là các ký tự không tự khớp như nhìn thấy mà có ý nghĩa đặc biệt khi dùng trong regex. Đơn giản, có thể coi chúng là các siêu ký tự dành riêng biểu thị thứ khác chứ không phải hình thức của chúng.

Hãy xem một vài ví dụ để thấy ký tự đặc biệt hoạt động...

Nhưng trước khi bắt đầu, các ví dụ dưới đây dùng hai hàm: search() và group().
Với hàm search, bạn quét qua chuỗi/sequence cho vị trí đầu tiên nơi regex tạo ra một khớp.
Hàm group trả về chuỗi được regex khớp. Bạn sẽ thấy cả hai chi tiết hơn ở phần sau.

Quay lại các ký tự đặc biệt.

. - Dấu chấm. Khớp bất kỳ ký tự đơn nào trừ ký tự xuống dòng.

re.search(r'Co.k.e', 'Cookie').group()
'Cookie'

^ - Dấu mũ. Khớp đầu chuỗi.

Hữu ích khi bạn muốn đảm bảo tài liệu/câu bắt đầu bằng một số ký tự nhất định.

re.search(r'^Eat', "Eat cake!").group()

## Tuy nhiên, đoạn mã dưới sẽ không cho kết quả giống vậy. Tự thử nhé:
# re.search(r'^eat', "Let's eat cake!").group()
'Eat'

$ - Khớp cuối chuỗi.

Hữu ích khi bạn muốn đảm bảo tài liệu/câu kết thúc bằng một số ký tự nhất định.

re.search(r'cake$', "Cake! Let's eat cake").group()

## Lần tìm kiếm tiếp theo sẽ trả về NONE, thử xem:
# re.search(r'cake$', "Let's get some cake on our way home!").group()
'cake'

[abc] - Khớp a hoặc b hoặc c.
[a-zA-Z0-9] - Khớp bất kỳ chữ cái từ (a đến z) hoặc (A đến Z) hoặc (0 đến 9).

MẸO: Các ký tự không nằm trong phạm vi có thể được khớp bằng cách bù trừ tập. Nếu ký tự đầu tiên của tập là ^, tất cả ký tự không nằm trong tập sẽ được khớp.

re.search(r'[0-6]', 'Number: 5').group()
'5'
## Khớp bất kỳ ký tự nào ngoại trừ 5
re.search(r'Number: [^5]', 'Number: 0').group()

## Dòng này sẽ không khớp và do đó trả về NONE
#re.search(r'Number: [^5]', 'Number: 5').group()
'Number: 0'

\ - Dấu gạch chéo ngược.
Có lẽ là siêu ký tự đa dụng nhất!!

  • Nếu ký tự theo sau gạch chéo ngược là một ký tự thoát được nhận diện, thì sẽ lấy ý nghĩa đặc biệt của ký tự đó (Kịch bản 1)
  • Nếu ký tự theo sau \ không phải ký tự thoát được nhận diện, thì \ được xử lý như ký tự thông thường và giữ nguyên (Kịch bản 2).
  • \ có thể đặt trước mọi siêu ký tự để loại bỏ ý nghĩa đặc biệt của chúng (Kịch bản 3).
## (Kịch bản 1) Điều này coi '\s' là ký tự thoát, '\s' biểu thị khoảng trắng
re.search(r'Not a\sregular character', 'Not a regular character').group()
'Not a regular character'
## (Kịch bản 2) '\' được coi là ký tự thường, vì '\r' không phải ký tự thoát được nhận diện
re.search(r'Just a \regular character', 'Just a \regular character').group()
'Just a \regular character'
## (Kịch bản 3) '\s' được escape bằng một `\` bổ sung nên được hiểu là chuỗi literal '\s'
re.search(r'Just a \\sregular character', 'Just a \sregular character').group()
'Just a \\sregular character'

Có một tập hợp các chuỗi đặc biệt được định nghĩa sẵn bắt đầu bằng '\' và cũng rất hữu ích khi tìm kiếm và khớp. Hãy xem một vài cái...

\w - w thường. Khớp bất kỳ chữ cái, chữ số, hoặc gạch dưới đơn lẻ.
\W - W hoa. Khớp bất kỳ ký tự nào không thuộc \w (w thường).

print("Lowercase w:", re.search(r'Co\wk\we', 'Cookie').group())

## Khớp mọi ký tự ngoại trừ chữ cái, chữ số hoặc gạch dưới đơn lẻ
print("Uppercase W:", re.search(r'C\Wke', 'C@ke').group())

## W hoa sẽ không khớp chữ cái, chữ số
print("Uppercase W won't match, and return:", re.search(r'Co\Wk\We', 'Cookie'))
Lowercase w: Cookie
Uppercase W: C@ke
Uppercase W won't match, and return: None

\s - s thường. Khớp một ký tự khoảng trắng như: dấu cách, xuống dòng, tab, return.
\S - S hoa. Khớp bất kỳ ký tự nào không thuộc \s (s thường).

print("Lowercase s:", re.search(r'Eat\scake', 'Eat cake').group())
print("Uppercase S:", re.search(r'cook\Se', "Let's eat cookie").group())
Lowercase s: Eat cake
Uppercase S: cookie

\d - d thường. Khớp chữ số thập phân 0-9.
\D - D hoa. Khớp bất kỳ ký tự nào không phải chữ số thập phân.

# Ví dụ cho \d
print("How many cookies do you want? ", re.search(r'\d+', '100 cookies').group())
How many cookies do you want?  100

Ký hiệu + dùng sau \d trong ví dụ trên được dùng cho lặp. Bạn sẽ thấy chi tiết hơn ở phần lặp phía sau...

\t - t thường. Khớp tab.
\n - n thường. Khớp xuống dòng.
\r - r thường. Khớp return.
\A - A hoa. Chỉ khớp ở đầu chuỗi. Hoạt động xuyên nhiều dòng.
\Z - Z hoa. Chỉ khớp ở cuối chuỗi.
MẸO: ^ và \A về cơ bản giống nhau, $ và \Z cũng vậy. Ngoại trừ khi dùng chế độ MULTILINE. Tìm hiểu thêm trong phần cờ.

\b - b thường. Chỉ khớp đầu hoặc cuối từ.

# Ví dụ cho \t
print("\\t (TAB) example: ", re.search(r'Eat\tcake', 'Eat    cake').group())

# Ví dụ cho \b
print("\\b match gives: ",re.search(r'\b[A-E]ookie', 'Cookie').group())
\t (TAB) example:  Eat    cake
\b match gives:  Cookie

Lặp

Sẽ khá tẻ nhạt nếu bạn muốn tìm các mẫu dài trong một chuỗi. May mắn là mô-đun re xử lý lặp bằng các ký tự đặc biệt sau:

+ - Kiểm tra ký tự đứng trước xuất hiện một hoặc nhiều lần tính từ vị trí đó.

re.search(r'Co+kie', 'Cooookie').group()
'Cooookie'

* - Kiểm tra ký tự đứng trước xuất hiện không hoặc nhiều lần tính từ vị trí đó.

# Kiểm tra mọi lần xuất hiện của a hoặc o hoặc cả hai trong chuỗi đã cho
re.search(r'Ca*o*kie', 'Cookie').group()
'Cookie'

? - Kiểm tra ký tự đứng trước xuất hiện chính xác không hoặc một lần tính từ vị trí đó.

# Kiểm tra chính xác không hoặc một lần xuất hiện của a hoặc o hoặc cả hai trong chuỗi đã cho
re.search(r'Colou?r', 'Color').group()
'Color'

Nhưng nếu bạn muốn kiểm tra số lần lặp chính xác thì sao?

Ví dụ, kiểm tra tính hợp lệ của số điện thoại trong một ứng dụng. Mô-đun re cũng xử lý rất gọn bằng các regex sau:

{x} - Lặp chính xác x lần.
{x,} - Lặp ít nhất x lần hoặc nhiều hơn.
{x, y} - Lặp ít nhất x lần nhưng không quá y lần.

re.search(r'\d{9,10}', '0987654321').group()
'0987654321'

Các bộ định lượng + và * được gọi là tham lam. Bạn sẽ thấy điều này nghĩa là gì ở phần sau.

Nhóm trong Biểu thức Chính quy

Tính năng group của regex cho phép bạn tách các phần của văn bản khớp. Các phần của mẫu regex được bao bởi dấu ngoặc đơn () được gọi là nhóm. Dấu ngoặc không thay đổi nội dung khớp, mà tạo nhóm trong chuỗi đã khớp. Bạn đã dùng hàm group() suốt các ví dụ trong hướng dẫn này. Lệnh match.group() không đối số vẫn trả về toàn bộ văn bản đã khớp như thường lệ.

Hãy hiểu khái niệm này bằng ví dụ đơn giản. Hình dung bạn đang xác thực địa chỉ email và muốn kiểm tra tên người dùng và máy chủ. Đây là lúc bạn muốn tạo các nhóm riêng trong văn bản đã khớp.

statement = 'Please contact us at: support@datacamp.com'
match = re.search(r'([\w\.-]+)@([\w\.-]+)', statement)
if statement:
  print("Email address:", match.group()) # Toàn bộ văn bản đã khớp
  print("Username:", match.group(1)) # Tên người dùng (nhóm 1)
  print("Host:", match.group(2)) # Máy chủ (nhóm 2)
Email address: support@datacamp.com
Username: support
Host: datacamp.com

Một cách khác để làm tương tự là dùng dấu ngoặc <>. Cách này cho phép bạn tạo nhóm có tên. Nhóm có tên khiến mã của bạn dễ đọc hơn. Cú pháp tạo nhóm có tên là: (?P<name>...). Thay name bằng tên bạn muốn đặt cho nhóm. ... biểu thị phần cú pháp khớp còn lại. Xem ví dụ này hoạt động với cùng ví dụ như trước...

statement = 'Please contact us at: support@datacamp.com'
match = re.search(r'(?P<email>(?P<username>[\w\.-]+)@(?P<host>[\w\.-]+))', statement)
if statement:
  print("Email address:", match.group('email'))
  print("Username:", match.group('username'))
  print("Host:", match.group('host'))
Email address: support@datacamp.com
Username: support
Host: datacamp.com

MẸO: Bạn luôn có thể truy cập nhóm có tên bằng số thay vì tên. Nhưng khi số nhóm tăng, việc xử lý bằng số sẽ khó khăn. Vì vậy, hãy tập thói quen dùng nhóm có tên.

Khớp tham lam và không tham lam

Khi một ký tự đặc biệt khớp càng nhiều của chuỗi tìm kiếm càng tốt, đó gọi là "Khớp tham lam". Đây là hành vi mặc định của regex, nhưng đôi khi không mong muốn:

pattern = "cookie"
sequence = "Cake and cookie"

heading  = r'<h1>TITLE</h1>'
re.match(r'<.*>', heading).group()
'<h1>TITLE</h1>'

Mẫu <.*> đã khớp toàn bộ chuỗi, đến tận lần xuất hiện thứ hai của >.

Tuy nhiên, nếu bạn chỉ muốn khớp thẻ <h1> đầu tiên, bạn có thể dùng bộ định lượng không tham lam *? để khớp ít ký tự nhất có thể.

Thêm ? sau bộ định lượng khiến nó khớp theo kiểu không tham lam hoặc tối thiểu; tức là sẽ khớp ít ký tự nhất có thể. Khi chạy <.*>, bạn sẽ chỉ nhận được khớp với <h1>.

heading  = r'<h1>TITLE</h1>'
re.match(r'<.*?>', heading).group()
'<h1>'

Bảng tóm tắt

Bạn đã đi được một chặng đường dài với regex. Có rất nhiều thông tin và khái niệm cần nắm! Bảng sau đây tóm tắt tất cả những gì bạn đã thấy trong hướng dẫn này. Đừng lo nếu bạn chưa thể nắm hết các siêu ký tự ngay. Theo thời gian và luyện tập, bạn sẽ thấy sự khác biệt của chúng và biết khi nào dùng cái gì...

Hướng dẫn này không bàn hết tất cả chuỗi đặc biệt mà Python cung cấp. Xem tài liệu Thư viện Chuẩn để có danh sách đầy đủ.

Ký tự Chức năng
. Dấu chấm. Khớp bất kỳ ký tự đơn nào trừ ký tự xuống dòng.
^ Dấu mũ. Khớp mẫu ở đầu chuỗi.
\A A hoa. Chỉ khớp ở đầu chuỗi.
$ Dấu đô la. Khớp cuối chuỗi.
\Z Z hoa. Chỉ khớp ở cuối chuỗi.
[ ] Khớp tập ký tự bạn chỉ định bên trong.
\ ∙ Nếu ký tự theo sau gạch chéo ngược là ký tự thoát được nhận diện, sẽ lấy ý nghĩa đặc biệt của nó.
∙ Nếu không, gạch chéo ngược (\) được coi là ký tự thường và giữ nguyên.
∙ Có thể dùng trước mọi siêu ký tự để loại bỏ ý nghĩa đặc biệt của chúng.
\w w thường. Khớp bất kỳ chữ cái, chữ số, hoặc gạch dưới đơn lẻ.
\W W hoa. Khớp bất kỳ ký tự nào không thuộc \w (w thường).
\s s thường. Khớp một ký tự khoảng trắng như: dấu cách, xuống dòng, tab, return.
\S S hoa. Khớp bất kỳ ký tự nào không thuộc \s (s thường).
\d d thường. Khớp chữ số thập phân 0-9.
\D D hoa. Khớp bất kỳ ký tự nào không phải chữ số thập phân.
\t t thường. Khớp tab.
\n n thường. Khớp xuống dòng.
\r r thường. Khớp return.
\b b thường. Chỉ khớp đầu hoặc cuối từ.
+ Kiểm tra ký tự đứng trước xuất hiện một hoặc nhiều lần.
* Kiểm tra ký tự đứng trước xuất hiện không hoặc nhiều lần.
? ∙ Kiểm tra ký tự đứng trước xuất hiện chính xác không hoặc một lần.
∙ Chỉ định phiên bản không tham lam của +, *
{ } Kiểm tra số lần xuất hiện rõ ràng.
( ) Tạo nhóm khi khớp.
< > Tạo nhóm có tên khi khớp.

Bạn đã xử lý các kiến thức nền tảng của regex! Tuy vậy, còn một số khái niệm nữa có thể giúp bạn tạo ra những regex hiệu quả để tìm kiếm và khớp.

MẸO: Mặc dù regex rất mạnh mẽ và hữu ích, hãy cẩn trọng với các biểu thức dài, rối rắm khó cho người khác, và cả chính bạn, hiểu và bảo trì về sau.

Các hàm do 're' cung cấp

Thư viện re trong Python cung cấp nhiều hàm giúp công việc của bạn dễ dàng hơn. Bạn đã thấy một vài hàm như re.search(), re.match(). Hãy xem tiếp...

compile(pattern, flags=0)

Python xử lý regex như chuỗi. Tuy nhiên, với compile(), bạn có thể biên dịch một mẫu regex thành đối tượng biểu thức chính quy. Khi cần dùng một biểu thức nhiều lần trong cùng chương trình, dùng compile() để lưu đối tượng regex cho tái sử dụng sẽ hiệu quả hơn là lưu dưới dạng chuỗi. Vì các phiên bản đã biên dịch của những mẫu gần đây nhất được truyền vào compile() và các hàm khớp ở cấp mô-đun được lưu vào bộ đệm.

pattern = re.compile(r"cookie")
sequence = "Cake and cookie"
pattern.search(sequence).group()
'cookie'
# Tương đương với:
re.search(pattern, sequence).group()
'cookie'

search(pattern, string, flags=0)

Với hàm này, bạn quét qua chuỗi/sequence đã cho, tìm vị trí đầu tiên nơi regex tạo ra một khớp. Nó trả về đối tượng khớp nếu tìm thấy, ngược lại trả về None nếu không có vị trí nào trong chuỗi khớp mẫu. Lưu ý rằng None khác với việc tìm thấy một khớp có độ dài bằng không tại một điểm nào đó trong chuỗi.

pattern = "cookie"
sequence = "Cake and cookie"

re.search(pattern, sequence)
<re.Match object; span=(9, 15), match='cookie'>

match(pattern, string, flags=0)

Trả về đối tượng khớp nếu có từ không đến nhiều ký tự ở đầu chuỗi khớp mẫu. Nếu không, trả về None nếu chuỗi không khớp mẫu đã cho.

pattern = "C"
sequence1 = "IceCream"
sequence2 = "Cake"

# Không khớp vì "C" không ở đầu "IceCream"
print("Sequence 1: ", re.match(pattern, sequence1))
print("Sequence 2: ", re.match(pattern,sequence2).group())
Sequence 1:  None
Sequence 2:  C

search() so với match()

Hàm match() chỉ kiểm tra khớp ở đầu chuỗi (theo mặc định), trong khi search() kiểm tra khớp ở bất kỳ đâu trong chuỗi.

findall(pattern, string, flags=0)

Tìm tất cả khớp có thể trong toàn bộ sequence và trả về dưới dạng danh sách các chuỗi. Mỗi chuỗi trả về đại diện cho một kết quả khớp.

statement = "Please contact us at: support@datacamp.com, xyz@datacamp.com"

#'addresses' là danh sách lưu tất cả khớp có thể
addresses = re.findall(r'[\w\.-]+@[\w\.-]+', statement)
for address in addresses:
    print(address)
support@datacamp.com
xyz@datacamp.com

finditer(string, [position, end_position])

Tương tự findall() — tìm tất cả khớp có thể trong toàn bộ sequence nhưng trả về các đối tượng khớp regex dưới dạng iterator.

MẸO: finditer() có thể là lựa chọn tuyệt vời khi bạn muốn có thêm thông tin về kết quả tìm kiếm. Đối tượng khớp regex trả về không chỉ giữ chuỗi đã khớp mà còn cả vị trí của chúng trong văn bản gốc.

statement = "Please contact us at: support@datacamp.com, xyz@datacamp.com"

#'addresses' là danh sách lưu tất cả khớp có thể
addresses = re.finditer(r'[\w\.-]+@[\w\.-]+', statement)
for address in addresses:
    print(address)
<re.Match object; span=(22, 42), match='support@datacamp.com'>
<re.Match object; span=(44, 60), match='xyz@datacamp.com'>

sub(pattern, repl, string, count=0, flags=0)
subn(pattern, repl, string, count=0)

sub() là hàm thay thế. Nó trả về chuỗi nhận được bằng cách thay thế các lần xuất hiện không chồng lấp ngoài cùng bên trái của mẫu trong chuỗi bằng giá trị thay thế repl. Nếu không tìm thấy mẫu, chuỗi được trả về không đổi.

subn() tương tự sub(). Tuy nhiên, nó trả về một bộ gồm chuỗi mới và số lượng thay thế đã thực hiện trong câu lệnh.

statement = "Please contact us at: xyz@datacamp.com"
new_email_address = re.sub(r'([\w\.-]+)@([\w\.-]+)', r'support@datacamp.com', statement)
print(new_email_address)
Please contact us at: support@datacamp.com

split(string, [maxsplit = 0])

Hàm này tách chuỗi ở mọi nơi mẫu khớp và trả về danh sách. Nếu đối số tùy chọn maxsplit khác 0, thì tối đa 'maxsplit' lần tách sẽ được thực hiện.

statement = "Please contact us at: xyz@datacamp.com, support@datacamp.com"
pattern = re.compile(r'[:,]')

address = pattern.split(statement)
print(address)
['Please contact us at', ' xyz@datacamp.com', ' support@datacamp.com']

start() - Trả về chỉ số bắt đầu của khớp.
end() - Trả về chỉ số nơi khớp kết thúc.
span() - Trả về bộ gồm (bắt đầu, kết thúc) của vị trí khớp.

pattern = re.compile('COOKIE', re.IGNORECASE)
match = pattern.search("I am not a cookie monster")

print("Start index:", match.start())
print("End index:", match.end())
print("Tuple:", match.span())
Start index: 11
End index: 17
Tuple: (11, 17)

Cờ biên dịch

Bạn có để ý thuật ngữ re.IGNORECASE trong ví dụ cuối không? Bạn hiểu tầm quan trọng của nó chứ?

Hành vi của một biểu thức có thể được sửa đổi bằng cách chỉ định một giá trị cờ. Bạn có thể thêm cờ làm đối số bổ sung cho các hàm khác nhau trong hướng dẫn này. Một số cờ hữu ích:

IGNORECASE (I) - Cho phép khớp không phân biệt hoa thường.
DOTALL (S) - Cho phép . khớp mọi ký tự, kể cả xuống dòng.
MULTILINE (M) - Cho phép mỏ neo đầu chuỗi (^) và cuối chuỗi ($) khớp cả các dòng mới.
VERBOSE (X) - Cho phép bạn viết khoảng trắng và chú thích trong regex để dễ đọc hơn.

statement = "Please contact us at: support@DataCamp.com, xyz@DATACAMP.com"

# Dùng cờ VERBOSE giúp hiểu regex phức tạp
pattern = re.compile(r"""
[\w\.-]+ #First part
@ #Matches @ sign within email addresses
datacamp.com #Domain
""", re.X | re.I)

addresses = re.findall(pattern, statement)                       
for address in addresses:
    print("Address: ", address)
Address:  support@DataCamp.com
Address:  xyz@DATACAMP.com

MẸO: Bạn cũng có thể kết hợp nhiều cờ bằng toán tử OR theo bit |.

Nghiên cứu tình huống: Làm việc với Biểu thức Chính quy

Bây giờ bạn đã thấy regex hoạt động trong Python qua một số ví dụ, đã đến lúc thực hành! Trong nghiên cứu tình huống này, bạn sẽ áp dụng tất cả kiến thức.

Bạn sẽ làm việc với phần đầu của một ebook miễn phí có tựa "The Idiot", do Fyodor Dostoyevsky viết từ Dự án Gutenberg. Cuốn tiểu thuyết kể về Hoàng thân (Knyaz) Lev Nikolayevich Myshkin, một người chất phác với bản tính tốt bụng, đơn giản, khiến nhiều người lầm tưởng anh thiếu thông minh và sâu sắc. Tựa đề là một cách gọi mỉa mai về chàng trai trẻ này.

Bạn sẽ viết một số regex để phân tích văn bản và hoàn thành một vài bài tập.

import re
import requests
the_idiot_url = 'https://www.gutenberg.org/files/2638/2638-0.txt'

def get_book(url):
    # Sends a http request to get the text from project Gutenberg
    raw = requests.get(url).text
    # Discards the metadata from the beginning of the book
    start = re.search(r"\*\*\* START OF THIS PROJECT GUTENBERG EBOOK .* \*\*\*",raw ).end()
    # Discards the text starting Part 2 of the book
    stop = re.search(r"II", raw).start()
    # Keeps the relevant text
    text = raw[start:stop]
    return text

def preprocess(sentence):
    return re.sub('[^A-Za-z0-9.]+' , ' ', sentence).lower()

book = get_book(the_idiot_url)
processed_book = preprocess(book)
#print(processed_book)
  • Bài tập: Tìm số lần đại từ "the" xuất hiện trong kho ngữ liệu. Gợi ý: Dùng hàm len().
len(re.findall(r'the', processed_book))
302
  • Bài tập: Thử chuyển mọi trường hợp đơn lẻ độc lập của 'i' thành 'I' trong kho ngữ liệu. Đảm bảo không thay đổi các 'i' xuất hiện bên trong một từ:
processed_book = re.sub(r'\si\s', " I ", processed_book)
#print(processed_book)
  • Bài tập: Tìm số lần có trích dẫn ("") trong kho ngữ liệu.
len(re.findall(r'\”', book))
0
  • Bài tập: Những từ nào được nối bằng '--' trong kho ngữ liệu?
    Tự thử nhé! Hãy chia sẻ câu trả lời của bạn trong phần bình luận bên dưới.

Chúc mừng!

Bạn đã đi đến cuối hướng dẫn regex Python! Còn rất nhiều thứ để tiếp tục trên hành trình khoa học dữ liệu với Python.

Regex có thể đóng vai trò quan trọng trong giai đoạn tiền xử lý dữ liệu. Xem khóa học Cleaning Data in Python của DataCamp. Khóa học này dạy bạn cách khám phá dữ liệu tốt hơn bằng cách sắp xếp và làm sạch dữ liệu để phục vụ phân tích. Cuối khóa cũng có một nghiên cứu tình huống để bạn áp dụng kiến thức mới.

Xem thêm Hướng dẫn Thay thế Chuỗi trong Python.

Chủ đề
Python

Khóa học Python

Khóa học

Nhập môn Python

4 giờ
7.1M
Nắm vững phân tích dữ liệu với Python chỉ trong 4 giờ. Khóa học online này giúp bạn làm quen với giao diện Python và các thư viện phổ biến.
Xem chi tiếtRight Arrow
Bắt Đầu Khóa Học
Xem thêmRight Arrow
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem ThêmXem Thêm