字符串html
字符編碼python
咱們已經講過了,字符串也是一種數據類型,可是,字符串比較特殊的是還有一個編碼問題。git
由於計算機只能處理數字,若是要處理文本,就必須先把文本轉換爲數字才能處理。最先的計算機在設計時採用8個比特(bit)做爲一個字節(byte),因此,一個字節能表示的最大的整數就是255(二進制11111111=十進制255),若是要表示更大的整數,就必須用更多的字節。好比兩個字節能夠表示的最大整數是65535,4個字節能夠表示的最大整數是4294967295。github
因爲計算機是美國人發明的,所以,最先只有127個字母被編碼到計算機裏,也就是大小寫英文字母、數字和一些符號,這個編碼表被稱爲ASCII編碼,好比大寫字母A的編碼是65,小寫字母z的編碼是122。web
可是要處理中文顯然一個字節是不夠的,至少須要兩個字節,並且還不能和ASCII編碼衝突,因此,中國製定了GB2312編碼,用來把中文編進去。編程
你能夠想獲得的是,全世界有上百種語言,日本把日文編到Shift_JIS裏,韓國把韓文編到Euc-kr裏,各國有各國的標準,就會不可避免地出現衝突,結果就是,在多語言混合的文本中,顯示出來會有亂碼。 canvas
所以,Unicode應運而生。Unicode把全部語言都統一到一套編碼裏,這樣就不會再有亂碼問題了。瀏覽器
Unicode標準也在不斷髮展,但最經常使用的是用兩個字節表示一個字符(若是要用到很是偏僻的字符,就須要4個字節)。現代操做系統和大多數編程語言都直接支持Unicode。ruby
如今,捋一捋ASCII編碼和Unicode編碼的區別:ASCII編碼是1個字節,而Unicode編碼一般是2個字節。服務器
字母A用ASCII編碼是十進制的65,二進制的01000001;
字符0用ASCII編碼是十進制的48,二進制的00110000,注意字符'0'和整數0是不一樣的;
漢字中已經超出了ASCII編碼的範圍,用Unicode編碼是十進制的20013,二進制的01001110 00101101。
你能夠猜想,若是把ASCII編碼的A用Unicode編碼,只須要在前面補0就能夠,所以,A的Unicode編碼是00000000 01000001。
新的問題又出現了:若是統一成Unicode編碼,亂碼問題今後消失了。可是,若是你寫的文本基本上所有是英文的話,用Unicode編碼比ASCII編碼須要多一倍的存儲空間,在存儲和傳輸上就十分不划算。
因此,本着節約的精神,又出現了把Unicode編碼轉化爲「可變長編碼」的UTF-8編碼。UTF-8編碼把一個Unicode字符根據不一樣的數字大小編碼成1-6個字節,經常使用的英文字母被編碼成1個字節,漢字一般是3個字節,只有很生僻的字符纔會被編碼成4-6個字節。若是你要傳輸的文本包含大量英文字符,用UTF-8編碼就能節省空間:
字符 ASCII Unicode UTF-8 A 01000001 00000000 01000001 01000001 中 x 01001110 00101101 11100100 10111000 10101101 從上面的表格還能夠發現,UTF-8編碼有一個額外的好處,就是ASCII編碼實際上能夠被當作是UTF-8編碼的一部分,因此,大量只支持ASCII編碼的歷史遺留軟件能夠在UTF-8編碼下繼續工做。
搞清楚了ASCII、Unicode和UTF-8的關係,咱們就能夠總結一下如今計算機系統通用的字符編碼工做方式:
在計算機內存中,統一使用Unicode編碼,當須要保存到硬盤或者須要傳輸的時候,就轉換爲UTF-8編碼。
用記事本編輯的時候,從文件讀取的UTF-8字符被轉換爲Unicode字符到內存裏,編輯完成後,保存的時候再把Unicode轉換爲UTF-8保存到文件:
瀏覽網頁的時候,服務器會把動態生成的Unicode內容轉換爲UTF-8再傳輸到瀏覽器:
因此你看到不少網頁的源碼上會有相似的信息,表示該網頁正是用的UTF-8編碼。
python字符串的幾種表達方式,可使用單引號或雙引號括起來:
name = 'lixigli' user = "lixingli" print(name,user) >>lixingli lixingli
若是字符串包含有單引號但不含雙引號,則字符串會用雙引號括起來,不然用單引號括起來。對於這樣的輸入字符串,print() 函數會產生更易讀的輸出。
跨行的字面字符串可用如下幾種方法表示。使用續行符,即在每行最後一個字符後使用反斜線來講明下一行是上一行邏輯上的延續: 如下使用 \n 來添加新行:
>>> '"Isn\'t," she said.' '"Isn\'t," she said.' >>> print('"Isn\'t," she said.') "Isn't," she said. >>> s = 'First line.\nSecond line.' # \n 意味着新行 >>> s # 不使用 print(), \n 包含在輸出中 'First line.\nSecond line.' >>> print(s) # 使用 print(), \n 輸出一個新行 First line. Second line.
如下使用反斜線(\)來續行:
hello = "This is a rather long string containing\n\ several lines of text just as you would do in C.\n\ Note that whitespace at the beginning of the line is\ significant." print(hello)
注意,其中的換行符仍然要用\n表示--反斜槓後的換行符唄丟棄了。以上例子以下輸出:
This is a rather long string containing several lines of text just as you would do in C. Note that whitespace at the beginning of the line is significant.
或者,字符串能夠被"""(三個雙引號)或者'''(三個單引號)括起來。使用三引號時,換行符不須要轉義,他們會包含在字符串中,一下的例子使用了一個轉義符,避免在最開始產生一個不須要的空行。
print("""\ Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to """)
其輸出以下:
Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to
若是咱們使用「原始」字符串,那麼\n不會轉換成行,行末的反斜槓,以及源碼中的換行符 ,都將做爲數據包含在字符串內。例如:
hello = r"This is a rather long string containing\n\ several lines of text much as you would do in C." print(hello)
注意,r的意思是使用python中的原生字符 將會輸出:
This is a rather long string containing\n\ several lines of text much as you would do in C.
字符串可使用+運算符鏈接在一塊兒,或者使用*運算符重複:
>>> word = 'Help' + 'A' >>> word 'HelpA' >>> '<' + word*5 + '>' '<HelpAHelpAHelpAHelpAHelpA>'
兩個緊鄰的字面字符串將自動被串聯;商例的第一行也能夠寫成word = 'Help''A' ;這樣的操做只在兩個字面間有效,不能隨意用於字符串表達式中:
>>> 'str' 'ing' # <- 這樣操做正確 'string' >>> 'str'.strip() + 'ing' # <- 這樣操做正確 'string' >>> 'str'.strip() 'ing' # <- 這樣操做錯誤 File "<stdin>", line 1, in ? 'str'.strip() 'ing' ^ SyntaxError: invalid syntax
字符串能夠被索引;就像C語言同樣,字符串的第一個字符的索引爲0,沒有單獨的字符類型;一個字符就是長度爲一的字符串,就像icon編程語言同樣,子字符串可使用分切符來指定:用冒號分隔的兩個索引。
word = 'Help you' print(word[3]) #第四個字符 print(word[:2]) #第0到3個字符 print(word[2:4]) #第3到4個字符
其輸出以下: p He lp 默認的分切索引頗有用:默認的第一個索引爲零,第二個索引默認爲字符串能夠被分切的長度。
不一樣於C的字符的是,python字符串不能被改變,想一個索引位置賦值會致使錯誤:
>>> word[0] = 'x' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'str' object does not support item assignment >>> word[:1] = 'Splat' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'str' object does not support slice assignment
然而,用組合內容的方法來建立新的字符是簡單高效的:
>>> 'x' + word[1:] 'xelpA' >>> 'Splat' + word[4] 'SplatA'
在分切操做字符串時,有一個頗有用的規律: s[:i] + s[i:] 等於 s.
>>>word = 'Help A' >>> word[:2] + word[2:] 'HelpA' >>> word[:3] + word[3:] 'HelpA'
除了數字,Python也能操做字符串。字符串有幾種表達方式,可使用單引號或雙引號括起來:
>>> 'spam eggs' 'spam eggs' >>> 'doesn\'t' "doesn't" >>> "doesn't" "doesn't" >>> '"Yes," he said.' '"Yes," he said.' >>> "\"Yes,\" he said." '"Yes," he said.' >>> '"Isn\'t," she said.' '"Isn\'t," she said.'
Python中使用反斜槓轉義引號和其它特殊字符來準確地表示。 若是字符串包含有單引號但不含雙引號,則字符串會用雙引號括起來,不然用單引號括起來。對於這樣的輸入字符串,print() 函數會產生更易讀的輸出。 跨行的字面字符串可用如下幾種方法表示。使用續行符,即在每行最後一個字符後使用反斜線來講明下一行是上一行邏輯上的延續: 如下使用 \n 來添加新行:
>>> '"Isn\'t," she said.' '"Isn\'t," she said.' >>> print('"Isn\'t," she said.') "Isn't," she said. >>> s = 'First line.\nSecond line.' # \n 意味着新行 >>> s # 不使用 print(), \n 包含在輸出中 'First line.\nSecond line.' >>> print(s) # 使用 print(), \n 輸出一個新行 First line. Second line.
如下使用 反斜線(\) 來續行:
hello = "This is a rather long string containing\n\ several lines of text just as you would do in C.\n\ Note that whitespace at the beginning of the line is\ significant." print(hello)
注意,其中的換行符仍然要使用 \n 表示——反斜槓後的換行符被丟棄了。以上例子將以下輸出:
This is a rather long string containing several lines of text just as you would do in C. Note that whitespace at the beginning of the line is significant.
或者,字符串能夠被 """ (三個雙引號)或者 ''' (三個單引號)括起來。使用三引號時,換行符不須要轉義,它們會包含在字符串中。如下的例子使用了一個轉義符,避免在最開始產生一個不須要的空行。
print("""\ Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to """) 其輸出以下: Usage: thingy [OPTIONS] -h Display this usage message -H hostname Hostname to connect to
若是咱們使用"原始"字符串,那麼 \n 不會被轉換成換行,行末的的反斜槓,以及源碼中的換行符,都將做爲數據包含在字符串內。例如:
hello = r"This is a rather long string containing\n\ several lines of text much as you would do in C."
print(hello) 將會輸出:
This is a rather long string containing\n\ several lines of text much as you would do in C.
字符串可使用 + 運算符串鏈接在一塊兒,或者用 * 運算符重複: >>> word = 'Help' + 'A' >>> word 'HelpA' >>> '<' + word*5 + '>' '' 兩個緊鄰的字面字符串將自動被串連;上例的第一行也能夠寫成 word = 'Help' 'A' ;這樣的操做只在兩個字面值間有效,不能隨意用於字符串表達式中:
>>> 'str' 'ing' # <- 這樣操做正確 'string' >>> 'str'.strip() + 'ing' # <- 這樣操做正確 'string' >>> 'str'.strip() 'ing' # <- 這樣操做錯誤 File "<stdin>", line 1, in ? 'str'.strip() 'ing' ^ SyntaxError: invalid syntax
字符串能夠被索引;就像 C 語言同樣,字符串的第一個字符的索引爲 0。沒有單獨的字符類型;一個字符就是長度爲一的字符串。就像Icon編程語言同樣,子字符串可使用分切符來指定:用冒號分隔的兩個索引。
>>> word[4] 'A' >>> word[0:2] 'Hl' >>> word[2:4] 'ep'
默認的分切索引頗有用:默認的第一個索引爲零,第二個索引默認爲字符串能夠被分切的長度。
>>> word[:2] # 前兩個字符 'He' >>> word[2:] # 除了前兩個字符以外,其後的全部字符 'lpA'
不一樣於C字符串的是,Python字符串不能被改變。向一個索引位置賦值會致使錯誤:
>>> word[0] = 'x' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'str' object does not support item assignment >>> word[:1] = 'Splat' Traceback (most recent call last): File "<stdin>", line 1, in ? TypeError: 'str' object does not support slice assignment
然而,用組合內容的方法來建立新的字符串是簡單高效的:
>>> 'x' + word[1:] 'xelpA' >>> 'Splat' + word[4] 'SplatA'
在分切操做字符串時,有一個頗有用的規律: s[:i] + s[i:] 等於 s.
>>> word[:2] + word[2:] 'HelpA' >>> word[:3] + word[3:] 'HelpA'
對於有誤差的分切索引的處理方式也很優雅:一個過大的索引將被字符串的大小取代,上限值小於下限值將返回一個空字符串。
>>>word = 'Help A' >>> word[1:100] 'elpA' >>> word[10:] >>> word[2:1]
在索引中可使用負數,這樣會從右往左計數。例如:
>>>word = 'Help A' >>> word[-1] # 最後一個字符 'A' >>> word[-2] # 倒數第二個字符 'p' >>> word[-2:] # 最後兩個字符 'pA' >>> word[:-2] # 除了最後兩個字符以外,其前面的全部字符 'Hel' 但要注意, -0 和 0 徹底同樣,因此 -0 不會從右開始計數! >>> word[-0] # (既然 -0 等於 0) 'H'
超出範圍的負數索引會被截去多餘部分,但不要嘗試在一個單元素索引(非分切索引)裏使用:
>>> word[-100:] 'HelpA' >>> word[-10] # 錯誤 Traceback (most recent call last): File "<stdin>", line 1, in ? IndexError: string index out of range
有一個方法可讓您記住分切索引的工做方式,想像索引是指向字符之間,第一個字符左邊的數字是 0。接着,有n個字符的字符串最後一個字符的右邊是索引n,例如:
+---+---+---+---+---+ | H | e | l | p | A | +---+---+---+---+---+ 0 1 2 3 4 5 -5 -4 -3 -2 -1
第一行的數字 0...5 給出了字符串中索引的位置;第二行給出了相應的負數索引。分切部分從 i 到 j 分別由在邊緣被標記爲 i 和 j 的所有字符組成。 對於非負數分切部分,若是索引都在有效範圍內,分切部分的長度就是索引的差值。例如, word[1:3] 的長度是2。 內置的函數 len() 用於返回一個字符串的長度:
第一行的數字 0...5 給出了字符串中索引的位置;第二行給出了相應的負數索引。分切部分從 i 到 j 分別由在邊緣被標記爲 i 和 j 的所有字符組成。 對於非負數分切部分,若是索引都在有效範圍內,分切部分的長度就是索引的差值。例如, word[1:3] 的長度是2。 內置的函數 len() 用於返回一個字符串的長度:
>>> s = 'supercalifragilisticexpialidocious' >>> len(s) 34
最後一個常見的問題是如何輸出格式化的字符串。咱們常常會輸出相似'親愛的xxx你好!你xx月的話費是xx,餘額是xx'之類的字符串,而xxx的內容都是根據變量變化的,因此,須要一種簡便的格式化字符串的方式。 在Python中,採用的格式化方式和C語言是一致的,用%實現,舉例以下:
>>> 'Hello, %s' % 'world' 'Hello, world' >>> 'Hi, %s, you have $%d.' % ('Michael', 1000000) 'Hi, Michael, you have $1000000.'
另外一種方法是:
name = 'hello,{0} 的電話是{1}。' info = name.format('brutyli',13853966793) print(info)
其輸出以下:
hello,brutyli 的電話是13853966793。
你可能猜到了,%運算符就是用來格式化字符串的。在字符串內部,%s表示用字符串替換,%d表示用整數替換,有幾個%?佔位符,後面就跟幾個變量或者值,順序要對應好。若是隻有一個%?,括號能夠省略。
常見的佔位符有: