早期電腦發展時的所使用的ASCII只有128種,只能應付英文和數字以及一些基本的符號,所以發展出了Unicode來面對全世界所有的符號
\u 加上4碼16進位的數字表示Unicode 中的 256 個基本語言,前兩碼為類別,後兩碼為索引
\U 加上8碼16進位的數字為表示超出上述範圍內的字符,最左一位須為0,\N{name}用來指定字符名稱
(完整清單 http://www.unicode.org/charts/charindex.html)
python的unicodedata模組提供了下面兩個方向的轉換函數:
def unicode_test(value):
import unicodedata
name = unicodedata.name(value)
value2 = unicodedata.lookup(name)
print('value="%s", name="%s", value2="%s"' % (value, name, value2))
unicode_test('A')
unicode_test('$')
unicode_test('\u00a2')
unicode_test('\u20ac')
unicode_test('\u2603')
# 想知道é這個符號的編碼
place = 'café'
print(place)
unicode_test('é')
print('é'.encode('unicode-escape')) #這裡
unicode_test('\u00e9')
value="A", name="LATIN CAPITAL LETTER A", value2="A" value="$", name="DOLLAR SIGN", value2="$" value="¢", name="CENT SIGN", value2="¢" value="€", name="EURO SIGN", value2="€" value="☃", name="SNOWMAN", value2="☃" café value="é", name="LATIN SMALL LETTER E WITH ACUTE", value2="é" b'\\xe9' value="é", name="LATIN SMALL LETTER E WITH ACUTE", value2="é"
使用utf-8進行編碼與解碼
使用__encode()__來編碼字符串成我們看得懂的
編碼 | 說明 |
---|---|
'ascii' | ASCII 編碼 |
'utf-8' | 最常用的編碼 |
'latin-1' | ISO 8859-1 編碼 |
'cp-1252' | Windows 常用編碼 |
'unicode-escape' | Python 中 Unicode 的文本格式, \uxxxx 或者 \Uxxxxxxxx |
#編碼
snowman = '\u2603'
print(snowman)
print(snowman.encode('unicode-escape'))
print(len(snowman))
ds = snowman.encode('utf-8')
print(len(ds))
print(ds)
print('☃')
☃ b'\\u2603' 1 3 b'\xe2\x98\x83' ☃
#解碼
place = 'caf\u00e9'
print(place)
place_bytes = place.encode('utf-8')
print(place_bytes)
place2 = place_bytes.decode('utf-8')
print(place2)
café b'caf\xc3\xa9' café
# 方法一
print('%s' % 42)
print('%d' % 42)
print('%x' % 42)
print('%o' % 42)
print('%s' % 7.03)
print('%f' % 7.03)
print('%e' % 7.03)
print('%g' % 7.03)
print('%d%%' % 100)
print('混合搭配文字[%s],以及數字[%f]' % ('我是文字',87))
#可搭配數字做位數控制
print('%10d' % 42)
print('%10.4d' % 42)
print('%10.1f' % 42)
print('%.1f' % 42)
print('%-10d' % 42)
print('%-10.1f' % 42)
42 42 2a 52 7.03 7.030000 7.030000e+00 7.03 100% 混合搭配文字[我是文字],以及數字[87.000000] 42 0042 42.0 42.0 42 42.0
# 方法二
n = 42
f = 7.03
s = 'string cheese'
print('{} {} {}'.format(n, f, s))
print('{2} {0} {1}'.format(n, f, s))
print('{n} {f} {s}'.format(n=42, f=7.03, s='string cheese'))
# 使用字典傳入
d = {'n': 42, 'f': 7.03, 's': 'string cheese'}
print('{0[n]} {0[f]} {0[s]} {1}'.format(d, 'other')) #0表示format的第一個參數,1表示第二個參數
# 方法一中的format也可以用在新方法,採用:來做銜接
print('===========分隔線===========')
print('{0:d} {1:f} {2:s}'.format(n, f, s))
print('{n:d} {f:f} {s:s}'.format(n=42, f=7.03, s='string cheese'))
print('===========分隔線===========')
print('{0:10d} {1:10f} {2:10s}'.format(n, f, s)) #指定寬度
print('{0:>10d} {1:>10f} {2:>10s}'.format(n, f, s)) #右對齊
print('{0:<10d} {1:<10f} {2:<10s}'.format(n, f, s)) #左對齊
print('{0:^10d} {1:^10f} {2:^10s}'.format(n, f, s)) #置中對齊
print('{0:>010d} {1:>10.4f} {2:>10.4s}'.format(n, f, s)) #與舊方法不同,整數沒有經度設定項
print('{0:!^20s}'.format('BIG SALE')) #指定填充符號
42 7.03 string cheese string cheese 42 7.03 42 7.03 string cheese 42 7.03 string cheese other ===========分隔線=========== 42 7.030000 string cheese 42 7.030000 string cheese ===========分隔線=========== 42 7.030000 string cheese 42 7.030000 string cheese 42 7.030000 string cheese 42 7.030000 string cheese 0000000042 7.0300 stri !!!!!!BIG SALE!!!!!!
採用wiki的說法
正規表示式,又稱正則表達式、正規表示法、正規運算式、規則運算式、常規表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),
電腦科學的一個概念。正規表示式使用單個字串來描述、符合一系列符合某個句法規則的字串。
在很多文字編輯器裡,正則運算式通常被用來檢索、取代那些符合某個模式的文字。
簡單來說,就是可以用來匹配字串(source)__中的__規則(pattern)
import re #從標準函式庫引入
function | 功能 |
---|---|
re.match( pattern, source ) | 查看字串是否以規定的規則開頭 |
re.search( pattern, source ) | 會返回第一次成功的匹配值 (如果有成功) |
re.findall( pattern, source) | 會返回所有成功且不重複的匹配值 (如果有成功) |
re.split( pattern, source ) | 會根據 規則 將 字串 切分成若干段,返回由這些片段組成的list |
re.sub( pattern, replacement, source ) | 還需一個額外的參數 replacement,它會把 字串 中所有匹配規則的字串 替換成 replacement |
import re
# .group()可以叫出符合正規表達式的字串部分
print('----------match----------')
# 檢查'Young Frankenstein'是否以'You'開頭
result = re.match('You', 'Young Frankenstein')
if result:
print(result.group())
print('\n----------compile後match----------')
# 針對較複雜情況可以先編譯一個物件出來加速判斷
youpattern = re.compile('You')
result = youpattern.match('Young Frankenstein')
print(result)
if result:
print(result.group())
print('\n----------match使用.*找任何位置----------')
# "."為除「\n」之外的任何單個字元。 "*"為符合前面的子運算式零次或多次。
# 組合在一起則成為匹配任意長度任意字元(除「\n」)的規則
m = re.match('.*Frank', 'Young Frankenstein')
if m:
print(m.group())
print('\n----------search----------')
# 可以不用透過".*"來找任意位置的符合值
m = re.search('Frank', 'Young Frankenstein')
if m: # search返回物件
print(m.group())
print('\n----------findall----------')
# 尋找所有符合的
m = re.findall('n', 'Young Frankenstein')
print(m) # findall返回了一个列表
print('共找到', len(m), '筆符合值\n')
#尋找後方有一個字元的
m = re.findall('n..', 'Young Frankenstein')
print(m) # findall返回了一个列表
#尋找後方有一個字元(可以沒有)的
m = re.findall('n.?', 'Young Frankenstein')
print(m) # findall返回了一个列表
print('\n----------split----------')
# 利用規格做切割字串
m = re.split('n', 'Young Frankenstein')
print(m) # split返回了一个列表
print('\n----------sub----------')
# 利用規格做替換字串
m = re.sub('n', '?', 'Young Frankenstein')
print(m) # sub返回了一个列表
#尋找英文單字邊界
m = re.findall(r'\bFra', 'Young Frankenstein')
print(m) # findall返回了一个列表
----------match---------- You ----------compile後match---------- <_sre.SRE_Match object; span=(0, 3), match='You'> You ----------match使用.*找任何位置---------- Young Frank ----------search---------- Frank ----------findall---------- ['n', 'n', 'n', 'n'] 共找到 4 筆符合值 ['ng ', 'nke', 'nst'] ['ng', 'nk', 'ns', 'n'] ----------split---------- ['You', 'g Fra', 'ke', 'stei', ''] ----------sub---------- You?g Fra?ke?stei? ['Fra']
特殊字元 | 功能 |
---|---|
. | 代表任意除 \n 外的字元 |
* | 表示任意多個字元(包括 0 個) |
? | 表示可選字元( 0 個或 1 個) |
\d | 一個數字字元。等價於[0-9] |
\D | 一個非數字字元。等價於[^0-9] |
\w | 一個 字母 或 數字 包括底線字元。等價於[A-Za-z0-9_] |
\W | 一個 非字母 非數字 非底線字元。等價於[^A-Za-z0-9_] |
\s | 空白字元。等價於[ \f\n\r\t\v] |
\S | 非空白字元。等價於[^ \f\n\r\t\v] |
\b | 單詞邊界(一個 \w 與 \W 之間的範圍,順序可逆) |
\B | 非單詞邊界 |
import string
printable = string.printable #100個ASCII字元
len(printable)
print(printable[0:50])
print(printable[50:])
print(re.findall('\d', printable)) #找數字
print(re.findall('\w', printable)) #找字母與數字
print(re.findall('\s', printable)) #找空白
0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMN OPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '_'] [' ', '\t', '\n', '\r', '\x0b', '\x0c']
直線符號(|)在markdown中的表格會變成區分格子用,我打不出來....請各位使用時自行替換
規則 | 功能 |
---|---|
abc | 文本值 abc |
(expr) | expr |
expr1 直線符號 expr2 | expr1 或 expr2 |
. | 除 \n 外的任何字元 |
^ | 源字元串的開頭 |
$ | 源字元串的結尾 |
prev? | 0 個或 1 個 prev |
prev* | 0 個或多個 prev,盡可能多地匹配 |
prev*? | 0 個或多個 prev,盡可能少地匹配 |
prev+ | 1 個或多個 prev,盡可能多地匹配 |
prev+? | 1 個或多個 prev,盡可能少地匹配 |
prev{m} | m 個連續的 prev |
prev{m, n} | m 到 n 個連續的 prev,盡可能多地匹配 |
prev{m, n}? | m 到 n 個連續的 prev,盡可能少地匹配 |
[abc] | a 或 b 或 c(和 a直線符號b直線符號c 一樣) |
[^abc] | 非(a 或 b 或 c) |
prev (?=next) | 如果後面為 next,返回 prev |
prev (?!next) | 如果後面非 next,返回 prev |
(?<=prev) next | 如果前面為 prev,返回 next |
(?<!prev) next | 如果前面非 prev,返回 next |
source = '''I wish I may, I wish I might
... Have a dish of fish tonight。'''
# 1. 找wish
print("1.", re.findall('wish', source))
# 2. 找wish或fish
print("2.", re.findall('wish|fish', source))
# 3. 找wish開頭
print("3.", re.findall('^wish', source))
# 4. 找I wish開頭
print("4.", re.findall('^I wish', source))
# 5. 找fish結束
print("5.", re.findall('fish$', source))
# 6. 找fish tonight(後面可以有無一個字元)
print("6.", re.findall('fish tonight.$', source))
# 7. 找fish tonight.(使用跳脫符號,表示\.為一個點而不是萬用字元)
print("7.", re.findall('fish tonight\.$', source))
# 8. 找wish與fish
print("8.", re.findall('[wf]ish', source))
# 9. 找w、s、h組合出來的字串
print("9.", re.findall('[wsh]+', source))
# 10. 找ght開頭,後面接著非字母 非數字 非底線字元
print("10.", re.findall('ght\W', source))
# 11. 找I開頭,後面是wish,但只返回前面
print("11.", re.findall('I (?=wish)', source))
# 12. 找前面開頭是I的wish,指返回後面
print("12.", re.findall('(?<=I) wish', source))
# 13. 原定希望找到fish然後前面是單詞邊界的地方,但是\b被當作是跳脫字元返回符號了
print("13.", re.findall('\bfish', source))
# 14. 所以採用r來宣告說我這是一個原始的字串,不需要自動轉換
print("14.", re.findall(r'\bfish', source))
print('\n--------------------')
#用括號筆規則做區分後可以透過groups()取得分開的tuple,並且可以透過<name>設定名稱
m = re.search(r'(. dish\b).*(\bfish)', source)
print(m.group())
print(m.groups())
m = re.search(r'(?P<DISH>. dish\b).*(?P<FISH>\bfish)', source)
print(m.group())
print(m.groups())
print(m.group('DISH'))
print(m.group('FISH'))
1. ['wish', 'wish'] 2. ['wish', 'wish', 'fish'] 3. [] 4. ['I wish'] 5. [] 6. ['fish tonight。'] 7. [] 8. ['wish', 'wish', 'fish'] 9. ['w', 'sh', 'w', 'sh', 'h', 'sh', 'sh', 'h'] 10. ['ght\n', 'ght。'] 11. ['I ', 'I '] 12. [' wish', ' wish'] 13. [] 14. ['fish'] -------------------- a dish of fish ('a dish', 'fish') a dish of fish ('a dish', 'fish') a dish fish
blist = [1, 2, 3, 255]
the_bytes = bytes(blist)
print(the_bytes)
the_byte_array = bytearray(blist)
print(the_byte_array)
the_byte_array[1] = 127 #可變
print(the_byte_array)
b'\x01\x02\x03\xff' bytearray(b'\x01\x02\x03\xff') bytearray(b'\x01\x7f\x03\xff')
import struct
valid_png_header = b'\x89PNG\r\n\x1a\n' #png的檔頭
data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR' + \
b'\x00\x00\x00\x9a\x00\x00\x00\x8d\x08\x02\x00\x00\x00\xc0' #一個圖檔的前段
if data[:8] == valid_png_header:
width, height = struct.unpack('>LL', data[16:24])
print('Valid PNG, width', width, 'height', height)
else:
print('Not a valid PNG')
#反過來轉換
print(struct.pack('>L', 154))
print(struct.pack('>L', 141))
print(struct.unpack('>2L', data[16:24]))
print(struct.unpack('>16x2L6x', data))
Valid PNG, width 154 height 141 b'\x00\x00\x00\x9a' b'\x00\x00\x00\x8d' (154, 141) (154, 141)
import binascii
#八字節轉十六bytes
valid_png_header = b'\x89PNG\r\n\x1a\n'
print(binascii.hexlify(valid_png_header))
#十六bytes轉八bytes
print(binascii.unhexlify(b'89504e470d0a1a0a'))
b'89504e470d0a1a0a' b'\x89PNG\r\n\x1a\n'