在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 字符串
附錄
進(jìn)程通信
操作系統(tǒng)
迭代器
模塊
描述符
裝飾器
第三部分 擴(kuò)展庫(kù)
內(nèi)置類型
數(shù)據(jù)存儲(chǔ)
數(shù)據(jù)類型
基本環(huán)境
文件與目錄
異常
程序框架
數(shù)學(xué)運(yùn)算
函數(shù)
元類
字符串
表達(dá)式

字符串

re

正則表達(dá)式是處理字符串最重要的一種手段。

http://wiki.jikexueyuan.com/project/the-python-study-notes-second-edition/images/3.png" alt="" />

http://wiki.jikexueyuan.com/project/the-python-study-notes-second-edition/images/4.png" alt="" />

正則函數(shù)

re 有幾個(gè)重要的函數(shù):

  • match(): 匹配字符串開(kāi)始位置。
  • search(): 掃描字符串,找到第一個(gè)位置。
  • findall(): 找到全部匹配,以列表返回。
  • finditer(): 找到全部匹配,以迭代器返回。

match 和 search 僅匹配一次,匹配不到返回 None。

>>> import re

>>> s = "12abc345ab"

>>> m = re.match(r"\d+", s)
>>> m.group(), m.span()
('12', (0, 2))

>>> m = re.match(r"\d{3,}", s)
>>> m is None
True

>>> m = re.search(r"\d{3,}", s)
>>> m.group(), m.span()
('345', (5, 8))

>>> m = re.search(r"\d+", s)
>>> m.group(), m.span()
('12', (0, 2))

findall 返回列表 (或空列表),finditer 和 match、search 一樣返回 MatchObject 對(duì)象。

>>> ms = re.findall(r"\d+", s)
>>> ms
['12', '345']

>>> ms = re.findall(r"\d{5}", s)
>>> ms
[]

>>> for m in re.finditer(r"\d+", s): print m.group(), m.span()
...
12 (0, 2)
345 (5, 8)

>>> for m in re.finditer(r"\d{5}", s): print m.group(), m.span() # 返回空列表
...
>>>

MatchObject

match、search、finditer 返回的對(duì)象 —— MatchObject。

  • group(): 返回匹配的完整字符串。
  • start(): 匹配的開(kāi)始位置。
  • end(): 匹配的結(jié)束位置。
  • span(): 包含起始、結(jié)束位置的元組。
  • groups(): 返回分組信息。
  • groupdict(): 返回命名分組信息。
>>> m = re.match(r"(\d+)(P<letter>[abc]+)", s)

>>> m.group()
'12abc'

>>> m.start()
0

>>> m.end()
5

>>> m.span()
(0, 5)

>>> m.groups()
('12', 'abc')

>>> m.groupdict()
{'letter': 'abc'}

group() 可以接收多個(gè)參數(shù),用于返回指定序號(hào)的分組。

>>> m.group(0)
'12abc'

>>> m.group(1)
'12'

>>> m.group(2)
'abc'

>>> m.group(1,2)
('12', 'abc')

>>> m.group(0,1,2)
('12abc', '12', 'abc')

start()、end() 和 span() 同樣能接收分組序號(hào)。和 group() 一樣,序號(hào) 0 表示整體匹配結(jié)果。

>>> m.start(0), m.end(0)
(0, 5)

>>> m.start(1), m.end(1)
(0, 2)

>>> m.start(2), m.end(2)
(2, 5)

>>> m.span(0)
(0, 5)

>>> m.span(1)
(0, 2)

>>> m.span(2)
(2, 5)

編譯標(biāo)志

可以用 re.I、re.M 等參數(shù),也可以直接在表達(dá)式中添加 "(iLmsux)" 標(biāo)志。

  • s: 單行。"." 匹配包括換行符在內(nèi)的所有字符。
  • i: 忽略大小寫(xiě)。
  • L: 讓 "\w" 能匹配當(dāng)?shù)刈址菜茖?duì)中文支持不好。
  • m: 多行。
  • x: 忽略多余的空白字符,讓表達(dá)式更易閱讀。
  • u: Unicode。

試試看。

>>> re.findall(r"[a-z]+", "%123Abc%45xyz&")
['bc', 'xyz']

>>> re.findall(r"[a-z]+", "%123Abc%45xyz&", re.I)
['Abc', 'xyz']

>>> re.findall(r"(i)[a-z]+", "%123Abc%45xyz&")
['Abc', 'xyz']

下面這么寫(xiě)好看多了吧?

>>> pattern = r"""
...     (\d+) # number
...     ([a-z]+) # letter
... """

>>> re.findall(pattern, "%123Abc\n%45xyz&", re.I | re.S | re.X)
[('123', 'Abc'), ('45', 'xyz')]

組操作

命名組:(P...)

>>> for m in re.finditer(r"(P<number>\d+)(P<letter>[a-z]+)", "%123Abc%45xyz&", re.I):
...     print m.groupdict()
...
{'number': '123', 'letter': 'Abc'}
{'number': '45', 'letter': 'xyz'}

無(wú)捕獲組:(:...),作為匹配條件,但不返回。

>>> for m in re.finditer(r"(:\d+)([a-z]+)", "%123Abc%45xyz&", re.I):
...     print m.groups()
...
('Abc',)
('xyz',)

反向引用:\ 或 (P=name),引用前面的組。

>>> for m in re.finditer(r"<a>\w+</a>", "%<a>123Abc</a>%<b>45xyz</b>&"):
...     print m.group()
...
<a>123Abc</a>

>>> for m in re.finditer(r"<(\w)>\w+</(\1)>", "%<a>123Abc</a>%<b>45xyz</b>&"):
...     print m.group()
...
<a>123Abc</a>
<b>45xyz</b>

>>> for m in re.finditer(r"<(P<tag>\w)>\w+</(P=tag)>", "%<a>123Abc</a>%<b>45xyz</
b>&"):
...     print m.group()
...
<a>123Abc</a>
<b>45xyz</b>

正聲明 (=...):組內(nèi)容必須出現(xiàn)在右側(cè),不返回。 負(fù)聲明 (...):組內(nèi)容不能出現(xiàn)在右側(cè),不返回。 反向正聲明 (<=):組內(nèi)容必須出現(xiàn)在左側(cè),不返回。 反向負(fù)聲明 (<):組內(nèi)容不能出現(xiàn)在左側(cè),不返回。

>>> for m in re.finditer(r"\d+(=[ab])", "%123Abc%45xyz%780b&", re.I):
...     print m.group()
...
123
780

>>> for m in re.finditer(r"(<\d)[a-z]{3,}", "%123Abc%45xyz%byse&", re.I):
... print m.group()
...
byse

更多信息請(qǐng)閱讀官方文檔或更專業(yè)的書(shū)籍。

修改

split: 用 pattern 做分隔符切割字符串。如果用 "(pattern)",那么分隔符也會(huì)返回。

>>> re.split(r"\W", "abc,123,x")
['abc', '123', 'x']

>>> re.split(r"(\W)", "abc,123,x")
['abc', ',', '123', ',', 'x']

sub: 替換子串??芍付ㄌ鎿Q次數(shù)。

>>> re.sub(r"[a-z]+", "*", "abc,123,x")
'*,123,*'

>>> re.sub(r"[a-z]+", "*", "abc,123,x", 1)
'*,123,x'

subn() 和 sub() 差不多,不過(guò)返回 "(新字符串,替換次數(shù))"。

>>> re.subn(r"[a-z]+", "*", "abc,123,x")
('*,123,*', 2)

還可以將替換字符串改成函數(shù),以便替換成不同的結(jié)果。

>>> def repl(m):
...     print m.group()
...     return "*" * len(m.group())
...

>>> re.subn(r"[a-z]+", repl, "abc,123,x")
abc
x
('***,123,*', 2)

StringIO

提供類文件接口的字符串緩沖區(qū),可選用性能更好的 cStringIO 版本。

>>> from contextlib import closing
>>> from cStringIO import StringIO

>>> with closing(StringIO("ab")) as f:
...     print >> f, "cd"
...     f.write("1234")
...     print f.getvalue()
abcd
1234

建議用 with 上下文確保調(diào)用 close() 方法釋放所占用內(nèi)存。用 getvalue() 返回字符串前,必須確保是打開(kāi)狀態(tài) (closed = False)。

struct

struct 看上去有點(diǎn)像 format,區(qū)別是它輸出的是二進(jìn)制字節(jié)序列??梢酝ㄟ^(guò)格式化參數(shù),指定類型、長(zhǎng)度、字節(jié)序(大小端)、內(nèi)存對(duì)齊等。

>>> from struct import *

>>> hexstr = lambda s: map(lambda c: hex(ord(c)), s)

>>> s = pack("i", 0x1234)

>>> hexstr(s)      # 4 字節(jié)整數(shù)小端排列
['0x34', '0x12', '0x0', '0x0']

>>> unpack("i", s)      # 還原。4660 = 0x1234
(4660,)

>>> s = pack(">i", 0x1234)    # 大端

>>> hexstr(s)
['0x0', '0x0', '0x12', '0x34']

>>> s = pack("2i2s", 0x12, 0x34, "ab")   # 多值。注意指定字符串長(zhǎng)度。

>>> hexstr(s)
['0x12', '0x0', '0x0', '0x0', '0x34', '0x0', '0x0', '0x0', '0x61', '0x62']

>>> unpack("2i2s", s)
(18, 52, 'ab')

還可以將結(jié)果輸出到 bytearray、array、ctypes.create_str_buffer() 等緩沖對(duì)象中。


>>> fmt = "3bi2s"
>>> size = calcsize(fmt)   # 計(jì)算指定格式轉(zhuǎn)換所需的字節(jié)長(zhǎng)度。

>>> buffer = bytearray(size)

>>> pack_into(fmt, buffer, 0, 0x1, 0x2, 0x3, 0x1FFFFF, "ab")

>>> buffer
bytearray(b'\x01\x02\x03\x00\xff\xff\x1f\x00ab')

>>> unpack_from(fmt, str(buffer), 0)
(1, 2, 3, 2097151, 'ab')
上一篇:附錄下一篇:內(nèi)置類型