官术网_书友最值得收藏!

2.7 字符串操作

字符串是Python中最常用的數(shù)據(jù)類型。我們可以使用引號(’或")創(chuàng)建字符串。

通常字符串不能進行數(shù)學操作,即使看起來像數(shù)字也不行。字符串不能進行除法、減法和字符串之間的乘法運算。下面的操作都是非法的。

        >>> 'hello'/3
        Traceback (most recent call last):
          File "<pyshell#83>", line 1, in <module>
            'hello'/3
        TypeError: unsupported operand type(s) for /: 'str' and 'int'
        >>> 'world'-1
        Traceback (most recent call last):
          File "<pyshell#84>", line 1, in <module>
            'world'-1
        TypeError: unsupported operand type(s) for -: 'str' and 'int'
        >>> 'hello'*world
        Traceback (most recent call last):
          File "<pyshell#85>", line 1, in <module>
            'hello'*world
        NameError: name 'world' is not defined
        >>> 'hello'-'world'
        Traceback (most recent call last):
          File "<pyshell#86>", line 1, in <module>
            'hello'-'world'
        TypeError: unsupported operand type(s) for -: 'str' and 'str'

字符串可以使用操作符+,但功能和數(shù)學中不一樣,它會進行拼接(concatenation)操作,即將前后兩個字符首尾連接起來。

例如:

        >>> string1='hello'
        >>> string2='world'
        >>> print(string1+string2)
        helloworld

輸出的字符緊緊挨著,看起來不怎么好看,能不能在兩個單詞間加一個空格呢?

如果想讓字符串之間有空格,就可以建一個空字符變量插在相應(yīng)的字符串之間,讓字符串隔開,或者在字符串中加入相應(yīng)的空格。交互模式下輸入如下:

        >>> string1='hello'
        >>> string2='world'
        >>> space=' '
        >>> print(string1+space+string2)
        hello world

或者

        >>> string1='hello'
        >>> string2=' world'
        >>>print(string1+string2)
        hello world

這些是字符串的一些簡單操作,在后續(xù)章節(jié)中會介紹更多、更實用的字符串操作。

小萌,你有沒有發(fā)現(xiàn)進行了這么多操作,操作中都沒有出現(xiàn)中文,這是怎么回事呢?

是啊,雖說一直用英文操作,在編碼時可以學習英文,但很多時候我還是喜歡用中文表達。我們目前沒有操作中文,是因為Python不支持中文嗎?

Python是支持中文的。正如我們前面所說,字符串也是一種數(shù)據(jù)類型,但是字符串特殊的是有編碼問題。

因為計算機只能處理數(shù)字,其實只認識0和1,即二進制。如果要處理文本,就必須先把文本轉(zhuǎn)換為數(shù)字才能處理。最早的計算機在設(shè)計時采用8比特(bit)為一個字節(jié)(byte),所以一個字節(jié)(8位)能表示的最大整數(shù)是255(二進制11111111等于十進制255,簡單表示為2**8-1=255)。如果要表示更大的整數(shù),就必須用更多字節(jié)。比如兩個字節(jié)(16位)可以表示的最大整數(shù)是65535(2**16-1),4個字節(jié)(32位)可以表示的最大整數(shù)是4294967295(2**32-1)。

由于計算機是美國人發(fā)明的,因此最早只有127個字母被編碼到計算機里,也就是大小寫英文字母、數(shù)字和一些符號,這個編碼表被稱為ASCII編碼。例如,大寫字母A的編碼是65,小寫字母z的編碼是122。

要處理中文,顯然一個字節(jié)是不夠的,至少需要兩個字節(jié),而且不能和ASCII編碼沖突,所以中國制定了GB2312編碼,用來把中文編進去。

可以想象,全世界有上百種語言,日本把日文編到Shift_JIS里,韓國把韓文編到Euc-kr里,各國有各國的標準,就不可避免地出現(xiàn)沖突。結(jié)果就是,在多語言混合的文本中就會顯示亂碼。當時各國對編碼問題的感覺如圖2-7所示。

圖2-7 令人頭疼的字符編碼

Unicode應(yīng)運而生。Unicode把所有語言都統(tǒng)一到一套編碼里,這樣就不會有亂碼問題了。

Unicode標準在不斷發(fā)展,最常用的是用兩個字節(jié)表示一個字符(如果要用到非常生僻的字符,就需要4個字節(jié))。現(xiàn)代操作系統(tǒng)和大多數(shù)編程語言都直接支持Unicode。

下面我們來看ASCII編碼和Unicode編碼的區(qū)別:ASCII編碼是1個字節(jié),而Unicode編碼通常是兩個字節(jié)。

字母A用ASCII編碼是十進制的65,二進制的01000001。

字符0用ASCII編碼是十進制的48,二進制的00110000。注意字符0和整數(shù)0是不同的。

漢字“中”已經(jīng)超出了ASCII編碼的范圍,用Unicode編碼是十進制的20013,二進制的0100111000101101。

如果把ASCII編碼的A用Unicode編碼,只需要在前面補0就可以,因此A的Unicode編碼是0000000001000001。

新的問題又出現(xiàn)了:如果統(tǒng)一成Unicode編碼,亂碼問題從此消失了。但是寫的文本基本上全部是英文時,用Unicode編碼比ASCII編碼多一倍存儲空間,在存儲和傳輸上十分不劃算。

本著節(jié)約的精神,又出現(xiàn)了把Unicode編碼轉(zhuǎn)化為“可變長編碼”的UTF-8編碼。UTF-8編碼把一個Unicode字符根據(jù)不同的數(shù)字大小編碼成1~6個字節(jié),常用的英文字母被編碼成1個字節(jié),漢字通常是3個字節(jié),只有很生僻的字符才會被編碼成4~6個字節(jié)。如果你要傳輸?shù)奈谋景罅坑⑽淖址肬TF-8編碼就能節(jié)省空間,如表2-9所示。

表2-9 各種編碼方式比較

從表2-9可以發(fā)現(xiàn),UTF-8編碼有一個額外的好處,就是ASCII編碼實際上可以看成是UTF-8編碼的一部分,所以只支持ASCII編碼的大量歷史遺留軟件可以在UTF-8編碼下繼續(xù)工作。

搞清楚ASCII、Unicode和UTF-8的關(guān)系后,我們可以總結(jié)一下現(xiàn)在計算機系統(tǒng)通用的字符編碼工作方式:在計算機內(nèi)存中,統(tǒng)一使用Unicode編碼,當需要保存到硬盤或需要傳輸時,可以轉(zhuǎn)換為UTF-8編碼。

例如,用記事本編輯時,從文件讀取的UTF-8字符被轉(zhuǎn)換為Unicode字符到內(nèi)存;編輯完成后,保存時再把Unicode轉(zhuǎn)換為UTF-8保存到文件,如圖2-8所示。

圖2-8 字符轉(zhuǎn)換

瀏覽網(wǎng)頁時,服務(wù)器會把動態(tài)生成的Unicode內(nèi)容轉(zhuǎn)換為UTF-8再傳輸?shù)綖g覽器,如圖2-9所示。

圖2-9 服務(wù)器、瀏覽器中的字符串轉(zhuǎn)換

我們經(jīng)常看到很多網(wǎng)頁的源碼上有類似<meta charset="UTF-8" />的信息,表示該網(wǎng)頁用的UTF-8編碼。

在最新的Python 3版本中,字符串是以UTF-8編碼的。也就是說,Python 3的字符串支持多語言。比如在交互模式下輸入:

        >>> print(’你好,世界!')
        你好,世界!
        >>> print(’馕齉’)
        馕齉

注意 可以看到,在Python 3中,簡單和復(fù)雜的中文字符都可以正確輸出。Python 2中默認的編碼格式是ASCII,在沒修改編碼格式時無法正確輸出中文,在讀取中文時會報錯。Python 2使用中文的語法是在字符串前面加上前綴u。

主站蜘蛛池模板: 祁阳县| 宜昌市| 沙坪坝区| 清远市| 正蓝旗| 蒙城县| 七台河市| 闽清县| 廉江市| 兴国县| 夏津县| 邹城市| 百色市| 临桂县| 南漳县| 满洲里市| 安多县| 东阳市| 丹东市| 镇沅| 阳西县| 湄潭县| 怀化市| 徐州市| 托克托县| 南部县| 潜山县| 吐鲁番市| 株洲市| 扎鲁特旗| 兴业县| 呈贡县| 昂仁县| 游戏| 高唐县| 平江县| 阿拉尔市| 武汉市| 皮山县| 南澳县| 金沙县|