31 python faq3-python 中 的原始(raw)字符串
Python實戰-從菜鳥到大牛的進階之路 作者:極客學院 投票推薦 加入書簽 留言反饋
本篇源自 py2.7.9-docs 的 faq.pdf 中的“3.23 why can’t raw strings (r-strings) end with a backsh?”
更準確的說,原始字符串即以r修飾的字符串,不能以奇數個反斜杠結束;
原始字符串被設計用來作為一些處理器(主要是正則表達式引擎)的輸入。這種處理器會認為這種未匹配的末端反斜杠是種錯誤,所以,原始字符串也就不允許以奇數個反斜杠結束。反過來,他們允許你使用斜杠來表示轉義,包括\"表示",\t 表示 tab 等。當原始字符串用於這些處理器時,這個規則適用。
如果原始字符串不用於正則表達式等處理器,隻是簡單的代表一個字符串,那麽該串中的 \ 就是 \,而不再具有轉義的含義,這就是所謂的‘原始’。
下麵我會一步步的解釋字符串和原始字符串的區別
1.用於單獨的字符串表示:
簡單字符串中存在 \ 轉義行為,而原始字符串中 \n 就是 \n 字符
>>> s = "i have\na dream">>> r = r''i have\na dream''>>> print si havea dream>>> print ri have\na dream </pre>
2.原始字符串用於正則表達式中
我們使用 windows 路徑來做例子介紹原始字符串的一次轉義
>>> path = r"\this\is\a\path\" file "<stdin>", line 1 path = r"\this\is\a\path\" #原始字符串不允許單數個\結尾,不管是用於正則還是普通字串 ^syntaxerror: eol while scanning string literal>>> path = r"\this\is\a\path\ "[:-1] >>> path''\\this\\is\\a\\path\\''#定義了一個待匹配的字符串>>> reg1 = r''\\this\\is\\a\\path\\'' #定義了自然字符串表示的正則表達式>>> import re>>> g = re.match(reg1, path) #使用自然字符串進行匹配>>> print g.group\this\is\a\path\ #匹配到了結果,表示真實的\字符可以被自然字符串以\\匹配上>>> #\\轉義的結果就是\ </pre>
3.簡單字符串用於正則表達式中
讓我們使用上麵的 path 變量來製作簡單字符串用來匹配的例子
>>> reg2 = ''\\this\\is\\a\\path\\''>>> g = re.match(reg2, path) #竟然報異常了,根據異常的意思是行尾是虛假的轉義traceback (most recent callst): #下麵我們再探究原因,先把行尾的\\去掉,再次進行匹配 file "<stdin>", line 1, in <module> file "d:\python27\lib\re.py", line 137, in match return pile(pattern, gs).match(string) file "d:\python27\lib\re.py", line 244, in pile raise error, v # invalid expressionsre_constants.error: bogus escape (end of line)>>> reg2 = ''\\this\\is\\a\\path'' >>> g = re.match(reg, path) #按照原始字符串的理解,這裏應該可以匹配上的,但是沒有>>> print g.grouptraceback (most recent callst): file "<stdin>", line 1, in <module>attributeerror: ''nype'' object has no attribute ''group'' </pre>
為什麽會出現差異,又為什麽到處都建議正則匹配時要使用r''字符串''呢?
讓我們分析下原始字符串和簡單字符串的區別:簡單字符串如果想輸出‘\’,需要進行轉義即''''才會輸出一個''\'';那原始字符串想要輸出''\'',則直接寫即可''\''。
這裏有些亂,我覺得主要在於 str、repr 在搗亂:
>>> print path #這裏調用str,人們習慣的顯示方式\this\is\a\path\>>> path #這裏調用repr,真實的顯示方式(比str的顯示僅多了一層轉義)''\\this\\is\\a\\path\\'' </pre>
讓我們全部將真實的顯示方式當做參照物,即
path 的真實顯示是:''thisisapath''
簡單字符串的正則表達式 reg2 的真實顯示是:''thisisapath''
原始字符串的正則表達式 reg1 的真實顯示是:''thisisapath''
從真實的顯示來看匹配就容易理解的多了,而且沒有了原始和簡單字符串之分,都看做是正則引擎應用的串。從上麵可以看出 reg2中 隻能匹配\,而 path 中是 ,需要像 reg1 中的 來進行匹配。
追根溯源向來比較繞,還是簡單記住使用規則,匹配路徑 \ 字符,需要普通字符串輸入 4 個斜杠()匹配上,而原始字符串僅需要 2 個斜杠()即可匹配上。這也是鼓勵使用原始字符串進行正則匹配的原因。
更準確的說,原始字符串即以r修飾的字符串,不能以奇數個反斜杠結束;
原始字符串被設計用來作為一些處理器(主要是正則表達式引擎)的輸入。這種處理器會認為這種未匹配的末端反斜杠是種錯誤,所以,原始字符串也就不允許以奇數個反斜杠結束。反過來,他們允許你使用斜杠來表示轉義,包括\"表示",\t 表示 tab 等。當原始字符串用於這些處理器時,這個規則適用。
如果原始字符串不用於正則表達式等處理器,隻是簡單的代表一個字符串,那麽該串中的 \ 就是 \,而不再具有轉義的含義,這就是所謂的‘原始’。
下麵我會一步步的解釋字符串和原始字符串的區別
1.用於單獨的字符串表示:
簡單字符串中存在 \ 轉義行為,而原始字符串中 \n 就是 \n 字符
>>> s = "i have\na dream">>> r = r''i have\na dream''>>> print si havea dream>>> print ri have\na dream </pre>
2.原始字符串用於正則表達式中
我們使用 windows 路徑來做例子介紹原始字符串的一次轉義
>>> path = r"\this\is\a\path\" file "<stdin>", line 1 path = r"\this\is\a\path\" #原始字符串不允許單數個\結尾,不管是用於正則還是普通字串 ^syntaxerror: eol while scanning string literal>>> path = r"\this\is\a\path\ "[:-1] >>> path''\\this\\is\\a\\path\\''#定義了一個待匹配的字符串>>> reg1 = r''\\this\\is\\a\\path\\'' #定義了自然字符串表示的正則表達式>>> import re>>> g = re.match(reg1, path) #使用自然字符串進行匹配>>> print g.group\this\is\a\path\ #匹配到了結果,表示真實的\字符可以被自然字符串以\\匹配上>>> #\\轉義的結果就是\ </pre>
3.簡單字符串用於正則表達式中
讓我們使用上麵的 path 變量來製作簡單字符串用來匹配的例子
>>> reg2 = ''\\this\\is\\a\\path\\''>>> g = re.match(reg2, path) #竟然報異常了,根據異常的意思是行尾是虛假的轉義traceback (most recent callst): #下麵我們再探究原因,先把行尾的\\去掉,再次進行匹配 file "<stdin>", line 1, in <module> file "d:\python27\lib\re.py", line 137, in match return pile(pattern, gs).match(string) file "d:\python27\lib\re.py", line 244, in pile raise error, v # invalid expressionsre_constants.error: bogus escape (end of line)>>> reg2 = ''\\this\\is\\a\\path'' >>> g = re.match(reg, path) #按照原始字符串的理解,這裏應該可以匹配上的,但是沒有>>> print g.grouptraceback (most recent callst): file "<stdin>", line 1, in <module>attributeerror: ''nype'' object has no attribute ''group'' </pre>
為什麽會出現差異,又為什麽到處都建議正則匹配時要使用r''字符串''呢?
讓我們分析下原始字符串和簡單字符串的區別:簡單字符串如果想輸出‘\’,需要進行轉義即''''才會輸出一個''\'';那原始字符串想要輸出''\'',則直接寫即可''\''。
這裏有些亂,我覺得主要在於 str、repr 在搗亂:
>>> print path #這裏調用str,人們習慣的顯示方式\this\is\a\path\>>> path #這裏調用repr,真實的顯示方式(比str的顯示僅多了一層轉義)''\\this\\is\\a\\path\\'' </pre>
讓我們全部將真實的顯示方式當做參照物,即
path 的真實顯示是:''thisisapath''
簡單字符串的正則表達式 reg2 的真實顯示是:''thisisapath''
原始字符串的正則表達式 reg1 的真實顯示是:''thisisapath''
從真實的顯示來看匹配就容易理解的多了,而且沒有了原始和簡單字符串之分,都看做是正則引擎應用的串。從上麵可以看出 reg2中 隻能匹配\,而 path 中是 ,需要像 reg1 中的 來進行匹配。
追根溯源向來比較繞,還是簡單記住使用規則,匹配路徑 \ 字符,需要普通字符串輸入 4 個斜杠()匹配上,而原始字符串僅需要 2 個斜杠()即可匹配上。這也是鼓勵使用原始字符串進行正則匹配的原因。