鍍金池/ 教程/ Python/ Python FAQ3-python 中 的原始(raw)字符串
通過(guò) memcached 實(shí)現(xiàn)領(lǐng)號(hào)排隊(duì)功能及 python 隊(duì)列實(shí)例
利用 pypy 提高 python 腳本的執(zhí)行速度及測(cè)試性能
Python FAQ3-python 中 的原始(raw)字符串
Mongodb 千萬(wàn)級(jí)數(shù)據(jù)在 python 下的綜合壓力測(cè)試及應(yīng)用探討
Parallel Python 實(shí)現(xiàn)程序的并行多 cpu 多核利用【pp 模塊】
python simplejson 模塊淺談
服務(wù)端 socket 開發(fā)之多線程和 gevent 框架并發(fā)測(cè)試[python 語(yǔ)言]
python Howto 之 logging 模塊
python 之 MySQLdb 庫(kù)的使用
關(guān)于 python 調(diào)用 zabbix api 接口的自動(dòng)化實(shí)例 [結(jié)合 saltstack]
python 之利用 PIL 庫(kù)實(shí)現(xiàn)頁(yè)面的圖片驗(yàn)證碼及縮略圖
Python 通過(guò) amqp 消息隊(duì)列協(xié)議中的 Qpid 實(shí)現(xiàn)數(shù)據(jù)通信
python 中用 string.maketrans 和 translate 巧妙替換字符串
python linecache 模塊讀取文件用法詳解
Python 批量更新 nginx 配置文件
python 計(jì)算文件的行數(shù)和讀取某一行內(nèi)容的實(shí)現(xiàn)方法
python+Django 實(shí)現(xiàn) Nagios 自動(dòng)化添加監(jiān)控項(xiàng)目
多套方案來(lái)提高 python web 框架的并發(fā)處理能力
python 寫報(bào)警程序中的聲音實(shí)現(xiàn) winsound
python 調(diào)用 zabbix 的 api 接口添加主機(jī)、查詢組、主機(jī)、模板
對(duì) Python-memcache 分布式散列和調(diào)用的實(shí)現(xiàn)
使用 python 構(gòu)建基于 hadoop 的 mapreduce 日志分析平臺(tái)
一個(gè)腳本講述 python 語(yǔ)言的基礎(chǔ)規(guī)范,適合初學(xué)者
Python 編寫的 socket 服務(wù)器和客戶端
如何將 Mac OS X10.9 下的 Python2.7 升級(jí)到最新的 Python3.3
python 監(jiān)控文件或目錄變化
報(bào)警監(jiān)控平臺(tái)擴(kuò)展功能 url 回調(diào)的設(shè)計(jì)及應(yīng)用 [python 語(yǔ)言]
Python 處理 cassandra 升級(jí)后的回滾腳本
python 實(shí)現(xiàn) select 和 epoll 模型 socket 網(wǎng)絡(luò)編程
關(guān)于 B+tree (附 python 模擬代碼)
通過(guò) python 和 websocket 構(gòu)建實(shí)時(shí)通信系統(tǒng)[擴(kuò)展 saltstack 監(jiān)控]

Python FAQ3-python 中 的原始(raw)字符串

本篇源自 py2.7.9-docs 的 faq.pdf 中的“3.23 Why can’t raw strings (r-strings) end with a backslash?”

更準(zhǔn)確的說(shuō),原始字符串即以r修飾的字符串,不能以奇數(shù)個(gè)反斜杠結(jié)束;

原始字符串被設(shè)計(jì)用來(lái)作為一些處理器(主要是正則表達(dá)式引擎)的輸入。這種處理器會(huì)認(rèn)為這種未匹配的末端反斜杠是種錯(cuò)誤,所以,原始字符串也就不允許以奇數(shù)個(gè)反斜杠結(jié)束。反過(guò)來(lái),他們?cè)试S你使用斜杠來(lái)表示轉(zhuǎn)義,包括\"表示",\t 表示 TAB 等。當(dāng)原始字符串用于這些處理器時(shí),這個(gè)規(guī)則適用。

如果原始字符串不用于正則表達(dá)式等處理器,只是簡(jiǎn)單的代表一個(gè)字符串,那么該串中的 \ 就是 \,而不再具有轉(zhuǎn)義的含義,這就是所謂的‘原始’。

下面我會(huì)一步步的解釋字符串和原始字符串的區(qū)別

1.用于單獨(dú)的字符串表示:

簡(jiǎn)單字符串中存在 \ 轉(zhuǎn)義行為,而原始字符串中 \n 就是 \n 字符

>>> s = "i have\na dream"
>>> r = r'i have\na dream'
>>> print s
i have
a dream
>>> print r
i have\na dream

2.原始字符串用于正則表達(dá)式中

我們使用 windows 路徑來(lái)做例子介紹原始字符串的一次轉(zhuǎn)義

>>> path = r"\this\is\a\path\"
  File "<stdin>", line 1
    path = r"\this\is\a\path\"    #原始字符串不允許單數(shù)個(gè)\結(jié)尾,不管是用于正則還是普通字串
                             ^
SyntaxError: EOL while scanning string literal
>>> path = r"\this\is\a\path\ "[:-1] 
>>> path
'\\this\\is\\a\\path\\'        #定義了一個(gè)待匹配的字符串
>>> reg1 = r'\\this\\is\\a\\path\\' #定義了自然字符串表示的正則表達(dá)式
>>> import re
>>> g = re.match(reg1, path)    #使用自然字符串進(jìn)行匹配
>>> print g.group()
\this\is\a\path\               #匹配到了結(jié)果,表示真實(shí)的\字符可以被自然字符串以\\匹配上
>>>                            #\\轉(zhuǎn)義的結(jié)果就是\

3.簡(jiǎn)單字符串用于正則表達(dá)式中

讓我們使用上面的 path 變量來(lái)制作簡(jiǎn)單字符串用來(lái)匹配的例子

>>> reg2 = '\\this\\is\\a\\path\\'
>>> g = re.match(reg2, path)         #竟然報(bào)異常了,根據(jù)異常的意思是行尾是虛假的轉(zhuǎn)義
Traceback (most recent call last):  #下面我們?cè)偬骄吭?,先把行尾的\\去掉,再次進(jìn)行匹配
  File "<stdin>", line 1, in <module>
  File "D:\Python27\lib\re.py", line 137, in match
    return _compile(pattern, flags).match(string)
  File "D:\Python27\lib\re.py", line 244, in _compile
    raise error, v # invalid expression
sre_constants.error: bogus escape (end of line)

>>> reg2 = '\\this\\is\\a\\path'    
>>> g = re.match(reg, path)         #按照原始字符串的理解,這里應(yīng)該可以匹配上的,但是沒(méi)有
>>> print g.group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'

為什么會(huì)出現(xiàn)差異,又為什么到處都建議正則匹配時(shí)要使用r'字符串'呢?

讓我們分析下原始字符串和簡(jiǎn)單字符串的區(qū)別:簡(jiǎn)單字符串如果想輸出‘\’,需要進(jìn)行轉(zhuǎn)義即'\'才會(huì)輸出一個(gè)'\';那原始字符串想要輸出'\',則直接寫即可'\'。

這里有些亂,我覺(jué)得主要在于 str、repr 在搗亂:

>>> print path                     #這里調(diào)用str,人們習(xí)慣的顯示方式
\this\is\a\path\
>>> path                           #這里調(diào)用repr,真實(shí)的顯示方式(比str的顯示僅多了一層轉(zhuǎn)義)
'\\this\\is\\a\\path\\'

讓我們?nèi)繉⒄鎸?shí)的顯示方式當(dāng)做參照物,即

path 的真實(shí)顯示是:'\this\is\a\path\'
簡(jiǎn)單字符串的正則表達(dá)式 reg2 的真實(shí)顯示是:'\this\is\a\path'
原始字符串的正則表達(dá)式 reg1 的真實(shí)顯示是:'\\this\\is\\a\\path\\'
從真實(shí)的顯示來(lái)看匹配就容易理解的多了,而且沒(méi)有了原始和簡(jiǎn)單字符串之分,都看做是正則引擎應(yīng)用的串。從上面可以看出 reg2中\(zhòng) 只能匹配\,而 path 中是 \,需要像 reg1 中的 \\ 來(lái)進(jìn)行匹配。

追根溯源向來(lái)比較繞,還是簡(jiǎn)單記住使用規(guī)則,匹配路徑 \ 字符,需要普通字符串輸入 4 個(gè)斜杠(\\)匹配上,而原始字符串僅需要 2 個(gè)斜杠(\)即可匹配上。這也是鼓勵(lì)使用原始字符串進(jìn)行正則匹配的原因。