正則表達式

引入標準庫模塊re

match() 和 search():查找到一個匹配后就停止
  • match(pattern, string, flags=0):從字符串開頭開始匹配
# 做一次簡單的文本匹配/搜索操作時:

# match():從字符串開頭開始匹配,匹配失敗時返回None
m = re.match('My', 'My name is xuebi')
print(m)
print(m.group())    # 匹配到的內(nèi)容
print(m.start())    # 開始位置
print(m.end())    # 結(jié)束位置
print((m.start(), m.end()))    # (開始位置, 結(jié)束位置)
print(m.span())    # (開始位置, 結(jié)束位置)
# m.span() == (m.start(), m.end())

# <re.Match object; span=(0, 2), match='My'>
# My
# 0
# 2
# (0, 2)
# (0, 2)
# 做大量的匹配和搜索操作時:

# 編譯(預(yù)編譯模式):
# 功能上一樣尺锚,執(zhí)行速度更快
p = re.compile('[a-z]+')
m2 = p.match('aaaaMy name is xuebi')
m3 = p.match('xuebi is me')
print(m2)
print(m3)

if p.match('#xuebi is me'):
    print('yes')
else:
    print('no')

# <re.Match object; span=(0, 4), match='aaaa'>
# <re.Match object; span=(0, 5), match='xuebi'>
# no
  • search(pattern, string, flags=0):尋找首次匹配
m = re.search('xuebi', 'kele and xuebi are person? xubi is not.')    # 只找第一次出現(xiàn)的
print(m)
# —— <re.Match object; span=(9, 14), match='xuebi'>
findall() 和 finditer():查找字符串中所有的匹配項
# 預(yù)編譯模式
text = 'Today is 2/12/2019. Python starts 23/10/2019. Yesterday is 1-12-2019.'
p = re.compile('\d+[-/]\d+[-/]\d')    # [-/]:要么-拼卵,要么/(-或/)
  • findall(pattern, string, flags=0):尋找所有匹配項陕习,返回列表
lis = p.findall(text)
print(lis)
# ['2/12/2', '23/10/2', '1-12-2']
  • finditer(pattern, string, flags=0):尋找所有匹配項示血,返回迭代器對象
lis = p.finditer(text)
print(lis)
for item in lis:
    print(item)
    print(item.group())
# <callable_iterator object at 0x030CAC50>
# <re.Match object; span=(9, 15), match='2/12/2'>
# 2/12/2
# <re.Match object; span=(34, 41), match='23/10/2'>
# 23/10/2
# <re.Match object; span=(59, 65), match='1-12-2'>
# 1-12-2
  • split(pattern, string, maxsplit=0, flags=0)
msg = 'xuebi@qq.com'
lis = msg.split('@')
print(lis)
# —— ['xuebi', 'qq.com']

line = 'asdf fjdk;   afed,  fjek,asdf,   foo'
lis1 = re.split(r'[,;\s]+', line)    # 按逗號或分號或空白字符中一次或多次進行分割
lis2 = re.split(r'[,;\s]\s*', line)    # 按逗號或分號或空白字符且他們的后面再接0個或多個空白字符進行分割
print(lis1)    # 按原生字符串分割氧卧,\s匹配任意一個空白字符包括[ \t\n\r\f\v]
print(lis2)
# —— ['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
# —— ['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']

str.replace() 和 sub() 和 subn():

# 對于簡單的替換,可以用str.replace()方法
text = 'yeah, but no, but yeah, but no, but yeah'
text = text.replace('yeah', 'yes')
print(text)
# —— yes, but no, but yes, but no, but yes
  • sub(pattern, repl, string, count=0, flags=0)
# 對于復(fù)雜的替換蚜锨,可以用正則表達式中的sub()方法

# sub()替換匹配
p = re.compile(r'(\d+)/(\d+)/(\d+)')

text = 'Today is 12/2/2019. PyCon starts 10/23/2019.'
text = p.sub(r'\3-\1-\2', text)    # \3\2\1為group()對應(yīng)的組元素
print(text)
# —— Today is 2019-12-2. PyCon starts 2019-10-23.

# 對于更復(fù)雜的替換,可以傳遞一個替換回調(diào)函數(shù)來代替慢蜓。
# 一個替換回調(diào)函數(shù)的參數(shù)是一個Match對象亚再,也就是match()或者find()返回的對象。
# 使用group()方法來提取特定的匹配部分晨抡。
# 回調(diào)函數(shù)最后返回替換字符串氛悬。

from calendar import month_abbr

def change_date(m):
    mon_name = month_abbr[int(m.group(1))]
    return '{} {} {}'.format(m.group(2), mon_name, m.group(3))

text = 'Today is 12/2/2019. PyCon starts 10/23/2019.'
text = p.sub(change_date, text)
print(text)
# —— Today is 2 Dec 2019. PyCon starts 23 Oct 2019.
  • subn(pattern, repl, string, count=0, flags=0)
# subn():可查出替換了多少次
newtext, n = p.subn(change_date, text)
print(newtext)
print(n)
# Today is 2 Dec 2019. PyCon starts 23 Oct 2019.
# 0

類似的還有:
fullmatch(pattern, string, flags=0)
compile(pattern, flags=0)
purge()
template(pattern, flags=0)
......

【拓展】回調(diào)函數(shù)
解決模塊之間不能循環(huán)調(diào)用的問題

=================================

普通字符集


# 普通字符:普通的文本值代表自身,用于匹配非特殊字符
print(re.search('My', 'My name is xuebi'))    # My匹配My
# —— <re.Match object; span=(0, 2), match='My'>


# .:可匹配換行符\n以外的任意一個字符耘柱。
print(re.search('.', 'My name is xuebi'))    # 匹配一個非換行符
# —— <re.Match object; span=(0, 1), match='M'>

print(re.search('ab.', 'abCMy name is xuebi'))    # 匹配ab和一個非換行符
print(re.search('...', 'ab CMy name is xuebi'))    # 匹配三個非換行符
print(re.search('ab.', 'ab'))    # 匹配ab和一個非換行符
# —— <re.Match object; span=(0, 3), match='ab '>
# —— <re.Match object; span=(0, 3), match='ab '>
# —— None


# \:轉(zhuǎn)義字符
print(re.search('xuebi.', 'xuebi.com'))    # 匹配xuebi和一個非換行字符
print(re.search('xuebi\.', 'xuebi.com'))    # 匹配xuebi和一個.字符
print(re.search('xuebi\.', 'xuebicom'))    # 匹配xuebi和一個.字符
# —— <re.Match object; span=(0, 6), match='xuebi.'>
# —— <re.Match object; span=(0, 6), match='xuebi.'>
# —— None


# []:匹配中括號內(nèi)的一個字符(括號里內(nèi)容不限)
# 1. 中括號內(nèi)的字符可以全部列出如捅,如[abc]表示匹配字符a或b或c
# 2. 也可以使用-表示范圍,如[a-z]表示匹配所以小寫字母中的任意一個字符
# 3. 本文后續(xù)要介紹的如*调煎、+等特殊字符在中括號內(nèi)將失去特殊含義镜遣,如[*+()]表示匹配字符*或+或(或)
# 4. 本文后續(xù)要介紹的特殊字符集如\d、\w等也可以放入此中括號內(nèi)士袄,繼續(xù)保持特殊含義
# 5. 如果中括號內(nèi)的字符序列前面有一個^悲关,表示不匹配中括號內(nèi)的任何一個字符谎僻,如[^0-9]表示不匹配數(shù)字,a[^0-9]c不匹配a1c寓辱,但會匹配abc
# 6. 要匹配字符]艘绍,可以轉(zhuǎn)義它,或者把它放在中括號內(nèi)的首位秫筏,如a[()[\]{}]c或a[]()[{}]c都可以匹配到a]c
print(re.search('[abc]', 'a_xuebicom'))    # 匹配a或b或c
print(re.search('[a-z]', 'a_xuebicom'))    # 匹配a到z中任意一個
print(re.search('[*+()]', '(_xuebicom)'))    # 匹配字符 * 或 + 或 ( 或 )
print()
print(re.search('[^*+()]', '(_xuebicom)'))    # 匹配非字符 * 或 + 或 ( 或 )
print(re.search('[a[()[\]{}]]c', '(a]c_xuebicom)'))    # 匹配a或]或(或)或[或{或} 和 ]和c
# 等價于下一句
print(re.search('a[]()[{}]c', '(a]c_xuebicom)'))    # 匹配a 和]或(或)或[或{或} 和 c
# <re.Match object; span=(0, 1), match='a'>
# <re.Match object; span=(0, 1), match='a'>
# <re.Match object; span=(0, 1), match='('>
# 特殊字符集如\d诱鞠、\w等例子請往下看
# <re.Match object; span=(1, 2), match='_'>
# <re.Match object; span=(1, 4), match='a]c'>
# <re.Match object; span=(1, 4), match='a]c'>

特殊字符集

# \d:匹配任意一個數(shù)字字符,等價于[0-9]
# \D:匹配任意一個非數(shù)字字符这敬,等價于[^0-9]
# \s:匹配任意一個空白字符般甲,等價于[ \t\n\r\f\v]
# \S:匹配任意一個非空字符,等價于[^ \t\n\r\f\v]
# \w:匹配任意一個alphanumeric character鹅颊,等價于[a-zA-Z0-9_]
# \W:匹配任意一個non-alphanumeric character敷存,等價于[^a-zA-Z0-9_]

print(re.search('a\db', 'xba1b)'))    # 匹配a和一個數(shù)字字符和b
# a\db == a[0-9]b
print(re.search('a\Db', 'xbaAb)'))    # 匹配a和一個非數(shù)字字符和b
# a\Db == a[^0-9]b
print(re.search('a\sb', 'xba b)'))    # 匹配a和一個空白字符和b
# a\sb == a[ \t\n\r\f\v]b
print(re.search('a\Sb', 'xbaCb)'))    # 匹配a和一個非空白字符和b
# a\Sb == a[^ \t\n\r\f\v]b
print(re.search('a\wb', 'xba_b)'))    # 匹配a和一個alphanumeric character和b
# a\wb == a[a-zA-Z0-9_]b
print(re.search('a\Wb', 'xba b)'))    # 匹配a和一個non-alphanumeric character和b
# a\Wb == a[^a-zA-Z0-9_]b
# <re.Match object; span=(2, 5), match='a1b'>
# <re.Match object; span=(2, 5), match='aAb'>
# <re.Match object; span=(2, 5), match='a b'>
# <re.Match object; span=(2, 5), match='aCb'>
# <re.Match object; span=(2, 5), match='a_b'>
# <re.Match object; span=(2, 5), match='a b'>

# 【例子】
import string
printable = string.printable
print(re.findall('\d', printable))
# ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
print(re.findall('\w', printable), end='')
# ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
# 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
# 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
# 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
# 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
# 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
# 'Y', 'Z', '_']
print(re.findall('\s', printable))
# [' ', '\t', '\n', '\r', '\x0b', '\x0c']

print(re.findall('\w', 'abc' + '-/*' + '\u00ea' + '\u0115'))
# ['a', 'b', 'c', 'ê', '?']

數(shù)量

# prev*      :匹配0個或多個prev,盡可能多地匹配堪伍,貪婪模式
# prev*?     :匹配0個或多個prev锚烦,盡可能少地匹配,非貪婪模式
# prev+      :匹配1個或多個prev帝雇,盡可能多地匹配涮俄,貪婪模式
# prev+?     :匹配1個或多個prev,盡可能少地匹配尸闸,非貪婪模式
# prev?      :匹配0個或多個prev彻亲,盡可能多地匹配,貪婪模式
# prev??     :匹配0個或多個prev吮廉,盡可能少地匹配苞尝,非貪婪模式
# prev{m}    :匹配m個連續(xù)的prev
# prev{m,n}  :匹配m個到n個連續(xù)的prev,盡可能多地匹配宦芦,貪婪模式
# prev{m,n}? :匹配m個到n個連續(xù)的prev宙址,盡可能少地匹配,非貪婪模式

print(re.findall('ab*', 'ab'))
print(re.findall('ab*', 'a_ab_abbb'))
# ['ab']
# ['a', 'ab', 'abbb']
print(re.findall('ab*?', 'ab'))
print(re.findall('ab*?', 'a_ab_abbb'))
# ['a']
# ['a', 'a', 'a']
print(re.findall('ab+', 'abb'))
print(re.findall('ab+', 'a_ab_abbb'))
# ['abb']
# ['ab', 'abbb']
print(re.findall('ab+?', 'abb'))
print(re.findall('ab+?', 'a_ab_abbb'))
# ['ab']
# ['ab', 'ab']
print(re.findall('ab?', 'abb'))
print(re.findall('ab?', 'a_ab_abbb'))
# ['ab']
# ['a', 'ab', 'ab']
print(re.findall('ab??', 'abb'))
print(re.findall('ab??', 'a_ab_abbb'))
# ['a']
# ['a', 'a', 'a']
print(re.findall('a{3}', 'aaaa'))
print(re.findall('a{3}', 'a_aa_aaa'))
# ['aaa']
# ['aaa']
print(re.findall('a{1,3}', 'aaaaa'))
print(re.findall('a{1,3}', 'aaaaaaa'))
print(re.findall('a{1,3}', 'a_aa_aaa'))
# ['aaa', 'aa']
# ['aaa', 'aaa', 'a']
# ['a', 'aa', 'aaa']
print(re.findall('a{1,3}?', 'aa'))
print(re.findall('a{1,3}?', 'a_aa_aaa'))
# ['a', 'a']
# ['a', 'a', 'a', 'a', 'a', 'a']

# 可以在*或+或?的后面再添加一個?调卑,此時表示非貪婪模式匹配抡砂,Python中的正則表達式默認是貪婪模式匹配,它會在滿足整個表達式要求的前提下恬涧,盡可能多地去匹配字符

邊界

# ^prev:匹配以prev開頭的字符串
# prev$:匹配以prev結(jié)尾的字符串
# \b:單詞邊界注益。\b在Python中默認會被轉(zhuǎn)義為\x08表示退格,需要將整個正則表達式指定為原始字符串(在前面加個r)
# \B:非單詞邊界
# \Aprev:匹配以prev開頭的字符串
# prev\Z:匹配以prev結(jié)尾的字符串

print(re.findall('^ab_', 'ab_cd'))
print(re.findall('^.*_ab', '1+x_ab_cd_ab'))
# ['ab_']
# ['1+x_ab_cd_ab']
print(re.findall('_ab$', 'ab_cd_ab'))
print(re.findall('.*_ab$', '1+x_ab_cd_ab'))
# ['_ab']
# ['1+x_ab_cd_ab']
print(re.findall(r'\bfoo\b', ' foo foo.(foo)'))
print(re.findall(r'\bfoo\b', ' foobar _foo1'))
# ['foo', 'foo', 'foo']
# []
print(re.findall(r'py\B', 'pythonpy3py2'))
print(re.findall(r'py\B', 'py py.py!'))
# ['py', 'py', 'py']
# []
print(re.findall(r'\Aab', 'abcde'))
print(re.findall(r'\Aab', '_abcde'))
# ['ab']
print(re.findall(r'ab\Z', '123ab'))
print(re.findall(r'ab\Z', '123ab_'))
# ['ab']
# []

# 【例】
import re
s = 'I wish I may, I wish I might have a dish of fish tonight.'
m = re.search(r'(. dish\b).*(\bfish)', s)
print(m.group())
print(m.groups())
print(m.group(0))
print(m.group(1))
print(m.group(2))
# a dish of fish
# ('a dish', 'fish')
# a dish of fish
# a dish
# fish

分組

# (expr):將小括號內(nèi)的表達式作為一個分組溯捆,后面可以接表示數(shù)量的特殊字符
# expr1|expr2:匹配expr1或expr2丑搔,等價于[expr1expr2]
# \1:引用編號為1的分組匹配到的字符串。類似的還有\(zhòng)0\2\3...
# (?P<NAME>expr):類似于(expr),同時給分組制定了一個別名NAME低匙,注意時大寫的字母P
# (?P=NAME):引用別名為NAME的分組旷痕,當然也可以繼續(xù)使用編號形式引用分組,此時要加r制定為原始字符串顽冶。

print(re.findall('a(bc)?d', 'abcdd'))
print(re.findall('a(bc)?d', 'abcbcd'))
# ['bc']
# []
print(re.findall('p(i|u)g', 'pug_pig'))
# ['u', 'i']
print(re.findall(r'a(\d)b\1c\1d', 'a3b3c3d'))
# ['3']
print(re.findall(r'a(?P<quote>\d)b\1c(?P=quote)d', 'a3b3c3d'))
# ['3']

# 【例】
m2 = re.search(r'(?P<DISH>. dish\b).*(?P<FISH>\bfish)', s)
print(m2.groups())
print(m2.group())
print(m2.group('DISH'))
print(m2.group('FISH'))
print(m2.group(1))
print(m2.group(2))
# ('a dish', 'fish')
# a dish of fish
# a dish
# fish
# a dish
# fish

拓展語法

# (?:expr):非捕獲組(成為整體但不成組)
# prev(?=next):環(huán)視欺抗,如果后面為next,則返回prev
# prev(?!next):環(huán)視强重,如果后面不是next绞呈,則返回prev
# (?<=prev)next:環(huán)視,如果前面為prev间景,則返回next
# (?<!\d)next:環(huán)視佃声,如果前面不是prev,則返回next

print(re.findall('a(?:\d)+bc', 'a333bc'))
# print(re.findall(r'a(?:\d)+b\1c', 'a333bc'))    # 語法錯誤
# ['a333bc']
print(re.findall('ab(?=\d)', 'ab3_+'))    # ab后緊跟一個數(shù)字時倘要,輸出ab
# ['ab']
print(re.findall('ab(?!\d)', 'abc_+'))    # ab后緊跟一個非數(shù)字時圾亏,輸出ab
# ['ab']
print(re.findall('(?<=\d)ab', '_+1ab'))    # ab前緊跟一個數(shù)字時,輸出ab
# ['ab']
print(re.findall('(?<!\d)ab', '_+ab'))    # ab前緊跟一個非數(shù)字時封拧,輸出ab
# ['ab']

# 【例】
import re
line = 'asdf fjdk; afed, fjek,asdf, foo'
print(re.split(r'[;,\s]\s*', line))    # 使用多個分割符或者是分隔符周圍不確定的空格時志鹃,來分割一個字符串
print(re.split(r'(;|,|\s)\s*', line))    # 使用括號時被匹配的文本(那些分隔符)也將出現(xiàn)在結(jié)果列表中
print(re.split(r'(?:,|;|\s)\s*', line))    # 不想保留分割字符串到結(jié)果列表中去,但仍然需要使用到括號來分組正則表達式的話泽西, 確保你的分組是非捕獲分組曹铃,形如(?:...)
# ['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']
# ['asdf', ' ', 'fjdk', ';', 'afed', ',', 'fjek', ',', 'asdf', ',', 'foo']
# ['asdf', 'fjdk', 'afed', 'fjek', 'asdf', 'foo']

實例1 — — 字符串忽略大小寫的搜索替換

# 【實例1-1】為了在文本操作時忽略大小寫,你需要在使用re模塊的時候給這些操作提供re.IGNORECASE標志參數(shù)

import re
text = 'UPPER PYTHON, lower python, Mixed Python'
print(re.findall('python', text))
print(re.findall('python', text, flags=re.IGNORECASE))
print(re.sub('python', 'snake', text, flags=re.IGNORECASE))
# ['python']
# ['PYTHON', 'python', 'Python']
# UPPER snake, lower snake, Mixed snake

# 弊端:這樣不管原字符串中的是大寫捧杉、小寫或首字母大寫的python陕见,全替換為小寫的snake

# 【實例1-2】替換字符串能自動跟被匹配字符串的大小寫保持一致
import re
text = 'UPPER PYTHON, lower python, Mixed Python'
def matchcase(word):
    def replace(m):
        text = m.group()
        if text.isupper():
            return word.upper()
        elif text.islower():
            return word.lower()
        elif text[0].isupper():
            return word.capitalize()
        else:
            return word
    return replace

print(re.sub('python', matchcase('snake'), text, flags=re.IGNORECASE))
# UPPER SNAKE, lower snake, Mixed Snake

# matchcase('snake')返回了一個回調(diào)函數(shù)

# 【拓展】Python支持的其它正則表達式的標志位flags:
# re.A: 或re.ASCII,使\w/\W/d/\D/\s/\S/\b/\B只匹配ASCII字符味抖,不匹配Unicode字符评甜。
# re.I: 或re.IGNORECASE,忽略大小寫非竿,[A-Z]會匹配小寫字母蜕着。
# re.M: 或re.MULTILINE,多行模式红柱,改變^或$的默認行為。
# re.S: 或re.DOTALL蓖乘,Make the.special character match any character at all, including a newline; without this flag, .will match anything except a newline锤悄。
# re.U: 或re.UNICODE,默認使用此標志位嘉抒,\w/\W/d/\D/\s/\S/\b/\B會匹配Unicode字符零聚,如果指定了re.A標志,則re.U失效。
# re.X: 或re.VERBOSE隶症,允許整個正則表達式寫成多行政模,忽略空白字符,并可以添加#開頭的注釋蚂会,這樣更美觀淋样。

# 【實例】
import re
a = re.compile(r"""\d +  # the integral part
                    \.    # the decimal point
                    \d *  # some fractional digits""", re.X)
b = re.compile(r"\d+\.\d*")
print(a.match('10.2'))
print(b.match('10.2'))
# <re.Match object; span=(0, 4), match='10.2'>
# <re.Match object; span=(0, 4), match='10.2'>

# 【實例】一次指定多個標志位
import re
text = '''UPPER PYTHON
lower python
Mixed Python'''
print(re.sub('python$', 'snake', text))
# UPPER PYTHON
# lower python
# Mixed Python
print(re.sub('python$', 'snake', text, flags=re.IGNORECASE))
# UPPER PYTHON
# lower python
# Mixed snake
print(re.sub('python$', 'snake', text, flags=re.IGNORECASE|re.MULTILINE))
# UPPER snake
# lower snake
# Mixed snake
p = re.compile(r'python$', re.I|re.M)
print(p)
# re.compile('python$', re.IGNORECASE|re.MULTILINE)
print(p.sub('snake', text))
# UPPER snake
# lower snake
# Mixed snake
print(re.sub('(?im)python$', 'snake', text))
# UPPER snake
# lower snake
# Mixed snake

實例2 — — 最短匹配模式: 非貪婪

# 【實例2-1】試著用正則表達式匹配某個文本模式丘侠,但是它找到的是模式的最長可能匹配
import re
p = re.compile(r'"(.*)"')
text1 = 'Computer says "no."'
print(p.findall(text1))
text2 = 'Computer says "no." Phone says "yes."'
print(p.findall(text2))    # 默認是貪婪模式囤屹,(.*)會盡可能多的匹配博肋,只要后面有一個"就能滿足整個正則检号,所以匹配到最后一個冒號之前了
# ['no.']
# ['no." Phone says "yes.']

# 【實例2-2】修正2-1的問題在模式中的*操作符后面加上?修飾符
p2 = re.compile(r'"(.*?)"')
print(p2.findall(text2))
# ['no.', 'yes.']

實例3 — — 多行匹配

# 試著使用正則表達式去匹配一大塊的文本断医,而你需要跨越多行去匹配萌腿,當你用點.去匹配任意字符的時候嘉竟,忘記了點.不能匹配換行符\n的事實渐尿。
# 【實例3-1】試著去匹配C語言分割的注釋
import re
text1 = '/* this is a comment */'
text2 = '''/* this is a
multiline comment */
'''
p = re.compile(r'/\*(.*?)\*/')
print(p.findall(text1))    # 能正確匹配單行
print(p.findall(text2))    # . 點號不能匹配多行中的換行符余指,所以整體匹配失敗
# [' this is a comment ']
# []

# 【實例3-2】改進3-1捕犬,可以使用.|\n匹配所有字符,或者指定re.DOTALL標志位
p2 = re.compile(r'/\*((?:.|\n)*?)\*/')
print(p2.findall(text2))
p3 = re.compile(r'/\*(.*?)\*/', re.DOTALL)
print(p3)
print(p3.findall(text2))
# [' this is a\nmultiline comment ']
# re.compile('/\\*(.*?)\\*/', re.DOTALL)
# [' this is a\nmultiline comment ']

# 【例3-3】re.MULTILINE多行模式的用法

import re

text = 'This is some text -- with punctuation.\nA second line.'
pattern = r'(^\w+)|(\w+\S*$)'
single_line = re.compile(pattern)
multiline = re.compile(pattern, re.MULTILINE)

print('Single Line :')
for match in single_line.findall(text):
    print('  {!r}'.format(match))
print('Multline    :')
for match in multiline.findall(text):
    print('  {!r}'.format(match))

# Single Line :
#   ('This', '')
#   ('', 'line.')
# Multline    :
#   ('This', '')
#   ('', 'punctuation.')
#   ('A', '')
#   ('', 'line.')
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酵镜,一起剝皮案震驚了整個濱河市碉碉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笋婿,老刑警劉巖誉裆,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異缸濒,居然都是意外死亡足丢,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門庇配,熙熙樓的掌柜王于貴愁眉苦臉地迎上來斩跌,“玉大人,你說我怎么就攤上這事捞慌∫唬” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵啸澡,是天一觀的道長袖订。 經(jīng)常有香客問我,道長嗅虏,這世上最難降的妖魔是什么洛姑? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮皮服,結(jié)果婚禮上楞艾,老公的妹妹穿的比我還像新娘参咙。我一直安慰自己,他們只是感情好硫眯,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布蕴侧。 她就那樣靜靜地躺著,像睡著了一般两入。 火紅的嫁衣襯著肌膚如雪净宵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天谆刨,我揣著相機與錄音塘娶,去河邊找鬼。 笑死痊夭,一個胖子當著我的面吹牛刁岸,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播她我,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼虹曙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了番舆?” 一聲冷哼從身側(cè)響起酝碳,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎恨狈,沒想到半個月后疏哗,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡禾怠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年返奉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吗氏。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡芽偏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出弦讽,到底是詐尸還是另有隱情污尉,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布往产,位于F島的核電站被碗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏仿村。R本人自食惡果不足惜蛮放,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望奠宜。 院中可真熱鬧包颁,春花似錦、人聲如沸压真。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽滴肿。三九已至岳悟,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間泼差,已是汗流浹背贵少。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留堆缘,地道東北人滔灶。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像吼肥,于是被迫代替她去往敵國和親录平。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 搞懂Python 正則表達式用法 Python 正則表達式 正則表達式是一個特殊的字符序列缀皱,它能幫助你方便的檢查一...
    廈熱閱讀 1,585評論 0 2
  • 在前面我們已經(jīng)搞定了怎樣獲取頁面的內(nèi)容斗这,不過還差一步,這么多雜亂的代碼夾雜文字我們怎樣把它提取出來整理呢啤斗?下面就開...
    AromaMuzi閱讀 313評論 0 0
  • re模塊手冊 本模塊提供了和Perl里的正則表達式類似的功能表箭,不關(guān)是正則表達式本身還是被搜索的字符串,都可以...
    喜歡吃栗子閱讀 4,012評論 0 13
  • Python中的正則表達式(re) import rere.match #從開始位置開始匹配钮莲,如果開頭沒有則無re...
    BigJeffWang閱讀 7,093評論 0 99
  • 本文介紹了Python對于正則表達式的支持免钻,包括正則表達式基礎(chǔ)以及Python正則表達式標準庫的完整介紹及使用示例...
    Python程序媛閱讀 1,353評論 0 22