[Python] RegEx

Posted in :

RegEx 應該是每一個程式語言裡必學的項目了,因為太實用!


Python RegEx
https://www.w3schools.com/python/python_regex.asp

Python/Regular Expression
https://zh.wikibooks.org/zh-tw/Python/Regular_Expression


補充說明:

程式語言:Python
Package:re
re 官方文件

debug online:
Debuggex
regex101

功能:處理匹配字串

範例:

import re
re.search(pattern, string)

語法

'.'
  • 匹配除「\n」之外的任何單個字符
  • 例: a.c 匹配 abc1234 => abc
'^'
  • 匹配輸入字串的開始位置
  • 設定 RegExp 物件的 Multiline 屬性,可匹配「\n」或「\r」之後的位置
  • 例: ^ab 匹配 abc1234 => ab
'$'
  • 匹配輸入字串的結束位置
  • 設定 RegExp 物件的 Multiline 屬性,可匹配「\n」或「\r」之前的位置
  • 例: 34$ 匹配 abc1234 => 34
  • ‘ test ’ 可以匹配‘ test ’和‘ testtool ’,但‘ test$ ’只能匹配‘ test ’。
'*'
  • 匹配至少零次
  • 例: ac* 匹配 abc1234 => a
'+'
  • 匹配至少一次
  • 例: ab.+ 匹配 abc1234 => abc1234
'?'
  • 匹配零次或一次
  • 例: ab? 匹配 abc1234 => ab
'*?' '+?' '??'
  • 匹配模式是 non-greedy,符合的最少字串,預設為 greedy
  • 可用在(*,+,?,{n},{n,},{n,m})後面
  • 例: a+? 匹配 aaaaa => a
  • <*> 会匹配'<H1>title</H1>’整个字符串(贪婪匹配),使用 *? 可以只找出 <H1>(非贪婪匹配)
{m}
  • 匹配 m 次
  • 例: a{3} 匹配 aaaaa => aaa
{m,n}
  • 匹配次數介於 m & n 之間,省略 n 表示無限次
  • 例: a{1,3} 匹配 aaaaa => aaa
'\'
  • 使用限制字元
  • 例: a\+ 匹配 a+aaaa => a+
[]
  • 匹配字元集合
  • – 表示從某字元到某字元,例:[a-z]
  • ^ 表示排除字元,例:[^a-z],需放置最前面,不然當作字元 ‘^’
  • 例: [a\-z]b 匹配 a-baaa => -b
'|'
  • 例: (a|b)aa 匹配 a-baaa => baa
(...)
  • 取得匹配的子字串,並放進 group
  • 例: (a|b)aa 匹配 a-baaa => baa, \1 = b (match.group(0) = baa, match.group(1) = b)
(?aiLmsux)
  • 指定匹配方式
  • (?a) 讓 \w, \W, \b, \B, \d, \D, \s and \S 只依 ASCII 匹配
  • (?i) 忽略大小寫
  • (?L) 讓 \w, \W, \b, \B, \s and \S 依本地字符編碼 (Python 3.6 已被移除)
  • (?m) ^ $ 匹配不同行的頭和尾
  • (?s) ‘.’ 匹配全部,包括 \n
  • (?u) unicode 匹配 (Python 3 已移除,預設已為 unicode 匹配)
  • (?x) 忽略空白字符,且可以用 # 當作註解,可多行建立 pattern,利用 “””abc string”””
    • 例: (?x)t es #測試 匹配 test => tes
  • 可同時使用,例:(?imx)^aa 匹配 a-bA\n#AA => None 因 AA 被註解
(?:...)
  • 不取得匹配的子字串
  • 例: (?:a|b|c)1 匹配 abc1234 => c1
(?P<name>)
  • 增加別名
  • 例: (?P<aa>a|b|c)1 匹配 abc1234 => c1, group(‘aa’) = c
(?P=name)
  • 與別名的字串匹配
  • 例: (?P<aa>a|b|c)1234(?P=aa) 匹配 abc1234c => c1234c
(?#...)
  • 註解
  • 例: (?P:a|b|c)(?#comment)1234 匹配 abc1234 => c1234
(?=...)
  • 之後的字串需匹配,但不消耗字串且不放進 group
  • 例: abc(?=1234)123 匹配 abc1234 => abc123
(?!...)
  • 之後的字串需不匹配,但不消耗字串且不放進 group
  • 例: ab(?!\d).123 匹配 abc1234 => abc123
(?<=...)
  • 之前的字串需匹配,但不消耗字串且不放進 group
  • 例: c(?<=abc)123 匹配 abc1234 => c123
(?<!...)
  • 之前的字串需不匹配,但不消耗字串且不放進 group
  • 例: (?<!\d)c123 匹配 abc1234 => c123
(?(id/name)yes-pattern|no-pattern)
  • 若子字串匹配成立,則為 yes-pattern 否則為 no-pattern (可省略)
  • 例: (\d)?abc(?(1)\d|) 匹配 1abc1 或 abc 或 1abc 或 abc1
\A
  • 匹配輸入字串的開始位置,不受 Multiline 影響
  • 例: (?m)\Aabc 匹配 de\nabc => None
\b
  • 匹配單詞的開頭或結尾,也就是單詞的分界處
  • \b 在字符類裡使用代表退格,故建議使用 r’string’ 或 \\
  • 例: \\bhi\\b.* 匹配 history, hi a => hi a
\B
  • 匹配不是單詞開頭或結束的位置
  • 例: \B1234\B. 匹配 1234a1234c => 1234c
\d
  • 匹配數字 unicode 包括全部數字,在 (?a) 下同 [0-9]
  • unicode 數字
  • 例: 1\d 匹配 1234 => 12
\D
  • 匹配非數字 unicode 包括全部數字,在 (?a) 下同 [^0-9]
  • unicode 數字
  • 例: a\D 匹配 abc => ab
\s
  • 匹配空白字符 unicode 包括全部空白字符,在 (?a) 下同 [ \t\n\r\f\v]
  • unicode 空白字符
  • 例: a\s 匹配 a\nbc => a\n
\S
  • 匹配非空白字符 unicode 包括全部空白字符,在 (?a) 下同 [^ \t\n\r\f\v]
  • unicode 空白字符
  • 例: b\S 匹配 a\nbc => bc
\w
  • 匹配 word, unicode 包括全部 word,在 (?a) 下同 [a-zA-Z0-9_]
  • 例: b\w 匹配 a\nbc => bc
\W
  • 匹配非 word, unicode 包括全部 word,在 (?a) 下同 [^a-zA-Z0-9_]
  • 例: a\W 匹配 a\nbc => a\n
\Z
  • 匹配輸入字串的結尾位置,不受 Multiline 影響
  • 例: (?m)de\Z 匹配 de\nabc => None

Python re 的主要功能

Python 的 re 正则表达式模块定义了一系列函数,常量以及异常;同时,正则表达式被编译成‘ RegexObject ’实例,本身可以为不同的操作提供方法。接下来简要介绍一下这些函数的功能和用法。

compile

re.compile(pattern[, flags])

把正则表达式的模式和标识转化成正则表达式对象,供 match() 和 search() 这两个函数使用。

re 所定义的 flag 包括:

re.I 忽略大小写

re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依赖于当前环境

re.M 多行模式

re.S 即为’ . ’并且包括换行符在内的任意字符(’ . ’不包括换行符)

re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依赖于 Unicode 字符属性数据库

re.X 为了增加可读性,忽略空格和’ # ’后面的注释

例:以下两种用法结果相同:

A)

1
2
compiled_pattern = re.compile(pattern) 
result = compiled_pattern.match(string)

B)

1result = re.match(pattern, string)

search

re.search(pattern, string[, flags])

在字符串中查找匹配正则表达式模式的位置,返回 MatchObject 的实例,如果没有找到匹配的位置,则返回 None。

对于已编译的正则表达式对象来说(re.RegexObject),有以下 search 的方法:

search (string[, pos[, endpos]])

若 regex 是已编译好的正则表达式对象,regex.search(string, 0, 50) 等同于 regex.search(string[:50], 0)。

具体示例如下。

1
2
3
>>> pattern = re.compile("a") 
>>> pattern.search("abcde")     # Match at index 0 
>>> pattern.search("abcde", 1)  # No match;

match

re.match(pattern, string[, flags])

判断 pattern 是否在字符串开头位置匹配。对于 RegexObject,有:

match(string[, pos[, endpos]])

match() 函数只在字符串的开始位置尝试匹配正则表达式,也就是只报告从位置 0 开始的匹配情况,而 search() 函数是扫描整个字符串来查找匹配。如果想要搜索整个字符串来寻找匹配,应当用 search()。

split

re.split(pattern, string[, maxsplit=0, flags=0])

此功能很常用,可以将将字符串匹配正则表达式的部分割开并返回一个列表。对 RegexObject,有函数:

split(string[, maxsplit=0])

例如,利用上面章节中介绍的语法:

1
2
3
4
5
6
>>> re.split('\W+', 'test, test, test.') 
['test', 'test', 'test', ''] 
>>> re.split('(\W+)', ' test, test, test.') 
[' test ', ', ', ' test ', ', ', ' test ', '.', ''] 
>>> re.split('\W+', ' test, test, test.', 1) 
[' test ', ' test, test.']

对于一个找不到匹配的字符串而言,split 不会对其作出分割,如:

1
2
>>> re.split('a*', 'hello world') 
['hello world']

findall

re.findall(pattern, string[, flags])

在字符串中找到正则表达式所匹配的所有子串,并组成一个列表返回。同样 RegexObject 有:

findall(string[, pos[, endpos]])

示例如下:

1
2
#get all content enclosed with [], and return a list 
>>> return_list = re.findall("(\[.*?\])",string)

finditer

re.finditer(pattern, string[, flags])

和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,并组成一个迭代器返回。同样 RegexObject 有:

finditer(string[, pos[, endpos]])

sub

re.sub(pattern, repl, string[, count, flags])

在字符串 string 中找到匹配正则表达式 pattern 的所有子串,用另一个字符串 repl 进行替换。如果没有找到匹配 pattern 的串,则返回未被修改的 string。Repl 既可以是字符串也可以是一个函数。对于 RegexObject 有:

sub(repl, string[, count=0])

此语法的示例有:

1
2
3
>>> p = re.compile( '(one|two|three)') 
>>> p.sub( 'num', 'one word two words three words') 
'num word num words num words'

同样可以用以下方法,并指定 count 为 1(只替换第一个):

>>> p.sub( ‘num’, ‘ one word two words three words’, count=1)

‘ num word two words three words’

subn

re.subn(pattern, repl, string[, count, flags])

该函数的功能和 sub() 相同,但它还返回新的字符串以及替换的次数。同样 RegexObject 有:

subn(repl, string[, count=0])

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *