CS50P 7_Regular Expressions

Regular Expression (Regex)

A regular expression (shortened as regex or regexp; sometimes referred to as rational expression) is a sequence of characters that specifies a search pattern in text.

正規表示式

正規表示式(英語:Regular expression,常簡寫為regex、regexp或RE),又稱規律表達式、正規表達式、正規表示法、規則運算式、常規表示法,是電腦科學概念,用簡單字串來描述、符合文中全部符合指定格式的字串

正規表示式

why : 做過濾或驗證(錯誤,攻擊) 規範或限制文字的格式 提高效率

what : 描述一種字串匹配的規則模式

手機號碼規則

手機號碼 : 09xx-xxx-xxx

  • 一共有十位數
  • 開頭要是09
  • 接續的八個為阿拉伯數字

手機號碼檢查程式

nos = ["0933-123-456", "0833-123-456", "1933-123-456",
       "0933-A123-45", "1234-567-890", "0933-123-45" ]
for no in nos:
   no = no.replace('-','')
   if len(no)==10 and no.isdecimal():
      if no[0:2] == "09":
         print(f"{no:>12} is ok")
         continue
   print(f"{no:>12} is not ok")
0933123456 is ok
0833123456 is not ok
1933123456 is not ok
0933A12345 is not ok
1234567890 is not ok
 093312345 is not ok

身分證字號 規則

身分證字號 : A123456789

  • 一共有十位數
  • 開頭要是大寫英文字母
  • 接續的九個為阿拉伯數字

身分證字號檢查程式

ids = ["A123456789", "a123456789", "1234567890",
       "AA12345678", "A1234567890", "AAA", "123"]
for id in ids:
    if len(id)==10:
       if id[0].isalpha() and id[0].isupper():
          if id[1:].isdecimal():
              print(f"{id:>12} is ok")
              continue
    print(f"{id:>12} is not ok")
 A123456789 is ok
 a123456789 is not ok
 1234567890 is not ok
 AA12345678 is not ok
A1234567890 is not ok
        AAA is not ok
        123 is not ok

民國日期規則

民國日期 : 100 年 10 月 25 曰

  • 年的前面有 1-3 個阿拉伯數字
  • 月前面有 1-2 個阿拉伯數字
  • 曰前面有 1-2 個阿拉伯數字 (數字和年月曰中可有空白?) (數字之間可有空白?) ...

正規表示式測試網站

正規表示式 Token

特殊字元規則範例說明

[] 括號內的任何字元 [a-zA-Z0-9] 大小寫字母或數字
[^] 不在括號內的任何字元 [^abc]+ Anything but abc.
. 換行之外的單一字元 . . 中間有空白的兩個字
| 表示所有可能的條件 a|b a or b , pick one!

正規表示式 Token

Anchor 規則 範例 說明
^ 輸入的開頭 ^aaa 以aaa 開頭
$ 輸入的結尾 bbb$ 以bbb 結尾
() 小括弧內的字元形成群組 (dog)
\ 特殊符號

正規表示式 Quantifiers

重複表示 規則 範例 說明
? 未出現或出現一次 ba? b後面沒有a或一個a
* 未出現或出現多次 ba* b後面沒有a或多個a
+ 出現一次或多次 ba+ b後面有一個以上的a

正規表示式 Quantifiers

重複表示 規則 範例 說明
{m,n} 最少出現 m 次, 最多出現 n 次 a{3,6} 3到6個a
{n} 出現 n 次 a{3} 剛好三個a
{n,} 至少出現 n 次以上 a{3,} 3個a以上

正規表示式 特別序列(Special Sequences)

特別序列 說明
\b 單字的界線字元。
\B 字元的界線字元。
\d 數字,從 0 到 9 。
\D 非數字。
\s 各種空白符號,包含換行符號 \n 。
\S 非空白符號。
\w 任意文字字元,包括數字。
\W 非文字字元,包括空白符號。

手機號碼正規表示式

手機號碼 : 09xx-xxx-xxx

09\d{2}-\d{3}-\d{3}

09 xx xxx xxx
09 2digit 3digit 3digit
09 \d{2} \d{3} \d{3}

身分證字號正規表示式

身分證字號 : A123456789

part 1 part 2
A 123456789
1 uppercase letter 9 digit
[A-Z] \d{9}

[A-Z]\d{9}

民國日期正規表示式

民國日期 : 100 年 10 月 25 曰

\d{1,3}年\d{1,2}月\d{1,2}曰

100 10 25
1-3 digit 1-2 digit 1-2 digit
\d{1,3} \d{1,2} \d{1,2}

民國日期正規表示式

民國日期 : 100 年 10 月 25 曰 

\s*(\d{1,3})\s*年\s*(\d{1,2})\s*月\s*(\d{1,2})\s*

Using re Module

匯入Re模組

import re

re.search() 方法 re.search(pattern, string, flags=0) https://docs.python.org/zh-tw/3/library/re.html#re.search
找到符合規則的,便會得到一個 Match 物件 如果沒有找到,則會得到 None

手機號碼檢查使用正規表示式

import re

no = "0933-123-456"
res = re.search(r"09\d{2}-\d{3}-\d{3}", no)
print( f"serach {no:13} return {type(res)} res is {res}" )

no = "0933-123-56"
res = re.search(r"09\d{2}-\d{3}-\d{3}", no)
print( f"serach {no:13} return {type(res)} res is {res}" )
serach 0933-123-456  return <class 're.Match'> res is <re.Match object; span=(0, 12), match='0933-123-456'>
serach 0933-123-56   return <class 'NoneType'> res is None

手機號碼檢查使用正規表示式

import re
no = "0933-123-456"
if re.search(r"09\d{2}-\d{3}-\d{3}", no):
   print(f"{no} is ok")
else:
   print("{no} is not a phone number") 
0933-123-456 is ok

Match 物件

需要使用 group() 方法把找到的東西呈現出來

import re

no = "0933-123-456"
res = re.search(r"09\d{2}-\d{3}-\d{3}", "0933-123-456")
if res:
   print( f"serach {res.group()}" )
serach 0933-123-456

民國日期檢查使用正規表示式 -- 規則分組

import re

date = "100 年 10 月 25 曰"
res = re.search(r"\s*(\d{1,3})\s*年\s*(\d{1,2})\s*月\s*(\d{1,2})\s*曰", date)
if res:
  print(f"res.group() {res.group()}")
  print(f"res.group(0) {res.group(0)}") 
  print(f"res.group(1) {res.group(1)}")
  print(f"res.group(2) {res.group(2)}") 
  print(f"res.group(3) {res.group(3)}") 
res.group() 100 年 10 月 25 曰
res.group(0) 100 年 10 月 25 曰
res.group(1) 100
res.group(2) 10
res.group(3) 25

sub()方法取代指定的字串

re.sub(pattern, repl, string, count=0, flags=0)

  • pattern : 正則表示式
  • repl : 替换字串
  • string : 被替换原始字串。
  • count : 模式匹配後替换的最大次数,默認0表示替换所有的匹配
res = re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
print(res)
res = re.sub(r'prize - \w+', 'xxxx', 'first prize - Phoebe, second prize - Vivi, third prize - Ming')
print(res)
Baked Beans & Spam
first xxxx, second xxxx, third xxxx

CS50P 7_Regular Expressions

By wschen

CS50P 7_Regular Expressions

Learn about Regular Expressions (Regex) and how they can be used to validate phone numbers, ID numbers, and dates. Discover the re module and how to use it for pattern matching and string replacement.

  • 162