Xin ý kiến góp ý cho đoạn Code về sử dụng Regex trong Python

Em học đến phần Regex trong Python, em có làm 1 ví dụ với yêu cầu thế này:

Viết một chương trình Python để kiểm tra xem một chuỗi chỉ chứa
một tập ký tự nhất định (a-z, A-Z và 0-9) hay không .

Đoạn Code của e thế này:

import re
def is_check(string):
    charRe = re.compile(r'[a-zA-Z0-9]')
    string = charRe.search(string)
    return bool(string)

print(is_check("ABCDEFabcdef123450")) 
print(is_check("*&%@#!}{"))

Kết quả thu được:

True                                                                                                          
False 

Nhờ các anh/chị góp ý thêm cho em để Code hoàn thiện hơn ạ.

Điều kiện bi thiếu

print(is_check("A{`*}*}*}"))
=> True

=>

charRe = re.compile(r'[a-zA-Z0-9]+$')
2 Likes

Anh có thể giải thích giúp e vì sao lại phải thêm +$ được không ạ. Em cám ơn anh

mà anh ơi biểu thức Regex của anh đưa ra charRe = re.compile(r'[a-zA-Z0-9]+$')cũng chưa cho kq đúng trong trường hợp này :

print(is_check("***T"))
–>
KQ:True

À mình quên

charRe = re.compile(r'^[a-zA-Z0-9]+$')

Nó là kiểm tra từ kí tự đầu tiên đến ký tự cuối cùng của 1 string

2 Likes

Thế tại sao sau ký tự ^ không có dấu + mà trước ký tự $ lại phải có dấu + ạ ?

Cặp dấu [] tức là kiểm tra 1 ký tự duy nhất, vậy nên phải thêm + để biểu thị kiếm tra nhiều hơn 1 ký tự nằm trong [], và $ tức là string đó phải kết thúc bằng ký tự phía trước nó.
Ký tự ^ biểu thị string phải bắt đầu bằng ký tự nằm sau nó

2 Likes

Cảm ơn anh nhiều ạ. Em cũng hiểu sơ sơ rồi, bình thường nếu không bỏ ^$ vào thì nó sẽ khớp tại vị trí bất bỳ tức là nếu string có chứa ít nhất 1 ký tự thỏa mãn là nó đã trả về giá trị True rồi.

Em có tham khảo thêm đáp án thì thấy cách giải họ viết thế này:

import re
def is_check(string):
    charRe = re.compile(r'[^a-zA-Z0-9.]')
    string = charRe.search(string)
    return not bool(string)

print(is_check("ABCDEFabcdef123450")) 
print(is_check("*&%@#!}{"))

Trong Code có 1 số chỗ e chưa hiểu lắm.

  • ^ của họ lại đặt trong cặp[] chứ không ở bên ngoài giống cách của anh. Vậy đặt bê trong như vậy có nghĩa là thế nào ạ ?
  • Sao ở sau số 9 họ viết thêm dấu chấm . , em ko biết tác dụng của nó để làm gì, vì e bỏ đi thì thấy kq không thay đổi.
  • return not bool(string) và dòng lệnh này tại sao phải bỏ not vào đây ạ.

Anh có thể giải thích giúp e vs được không, e cảm ơn anh nhiều ạ

Bạn đang dùng hàm search, hàm để regex đúng phải là match
Nội dung của 2 hàm này bạn search trực tiếp trên tàu liệu nhé

Dấu . thêm vào tức là thực hiện tìm cả dấu chấm đó, tất cả các ký tự nằm trong [] đều được tính là 1 char (ngoại trừ thằng range) và sẽ được nhét vào trong quy tắc hết. Bài của bạn thì phải bỏ đi vì đề không cho phép dấu chấm.
not ở đây là phủ định lại true, giả sử bạn search ra true thì nó sẽ trả về false

2 Likes

Hình như anh chưa giải thích cho e chổ này ạ.

Còn not --> nó mang ý phủ định thì e biết rồi, vấn đề là em không hiểu tại sao phải thêm not vào đằng trước đó anh.

https://docs.python.org/2.0/lib/matching-searching.html

Viết code ra cho dễ hiểu:

2 Likes

re.compile(r'[^a-zA-Z0-9]')

Theo em hiểu thì dấu ^ đặt trước tập a-zA-Z0-9 và trong cặp []
mang ý nghĩa là phủ định : tức là nếu string chỉ cần chứa ít nhất 1 ký tự KHÔNG thuộc vào tập trên thì nó sẽ trả về True ngược lại nếu string KHÔNG chứa 1 ký tự nào KHÔNG thuộc vào tập trên thì sẽ trả về giá trị FALSE.
Không biết như vậy có đúng không. Mong anh cùng mọi người góp ý thêm ạ

Không phải nhé:

https://www.regular-expressions.info/anchors.html

2 Likes

Trong đó họ viết nó vẫn mang ý nghĩa là "khớp với vị trí trước ký tự đầu tiên trong chuỗi."
Nhưng mà sao với string này nó lại cho kq False hả anh.

import re

def is_allowed_specific_char(string):
    charRe = re.compile(r'[^a-zA-Z0-9]')
    string = charRe.search(string)
    return bool(string)
    
print(is_allowed_specific_char("ABCDEFabcdef123450")) ---> Flase

Em tìm được bài này:


Người ta cũng nói như ý của em mà, hay là không biết Python có ngoại lệ không ?

anh ơi, Sao không thấy anh phản hồi lại ạ

Hm…cứ print hết ra là hiểu vấn đề thôi. Mình sẽ đi từ trên xuống theo code bạn paste nhé :wink:
Giải sử ta có 3 tập hợp

  • Các chữ cái từ A -> Z
  • Các chữ cái từ a -> z
  • Các chữ số từ 0 -> 9
    Mình sẽ gọi cái tập hợp gồm 3 tập hợp này là domain nhé.
def is_check(string):
    charRe = re.compile(r'[a-zA-Z0-9]')
    string = charRe.search(string)
    return bool(string

Cái này dùng để kiếm trong chuỗi string của bạn có kí tự nào thuộc domain hay không. Nếu so với đề bài của bạn thì nó trật lất, vì chỉ cần có một kí tự thuộc domain thôi là coi như True. Đi ngược lại việc kiểm tra xem một chuỗi chỉ chứa
một tập ký tự nhất định (a-z, A-Z và 0-9) hay không

def is_check(string):
    charRe = re.compile(r'[^a-zA-Z0-9.]')
    string = charRe.search(string)
    return not bool(string)

Mình sẽ chia làm hai phần, phần đầu tiên

charRe = re.compile(r'[a-zA-Z0-9.]')
string = charRe.search(string)

Đoạn này khi search, nó sẽ tìm kiếm những kí tự thuộc domain và dấu '.'. Dấu chấm ở đây không phải kiểu dấu chấm đại diện cho bất kì kí tự nào đâu. Nó là dấu '.'
Và khi

charRe = re.compile(r'[^a-zA-Z0-9.]')

Có nghĩa là bạn đi phủ định lại cái đó bằng ‘^’. Còn nếu đặt ở ngoài là báo cho nó tìm ở đầu chuỗi
Tóm gọn lại nó sẽ tìm kiếm những kí tự KHÔNG thuộc domain và dấu '.'

return not bool(string)

Đoạn này thì dễ hiểu, nếu trên tìm được thì kết quả là False, tìm không được là True.
Cuối cùng thì cái đoạn code trên ấy, nó là một cách tuyệt vời để hoàn thành đề bài của bạn. Vì nó tìm phủ đinh nên sẽ tìm rộng hơn cái ban đầu của bạn :wink:

2 Likes

Em hiểu rồi. Cảm ơn anh nhiều ạ

Anh cho e hỏi thêm ý này nữa ạ.
Giữa 2 cách viết này có gì khác nhau ạ:

import re
tr = 'hello word'
kq = re.findall(r'h\w+',tr)
print kq

import re
tr = 'hello word'
kq = re.findall('h\w+',tr)
print kq

Khác nhau ở chỗ cách trên trong biểu thức chính quy có chữ r còn cách dưới thì không. Em ko biết chữ r đó có ý nghĩa gì ạ ?

r đó trước 1 string để biểu thị cho raw string.

Phải có r vì string thường sẽ không hiểu \ là kí tự \, còn raw_string thì có.

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?