- 論壇徽章:
- 0
|
引言
QUOTE:你在編輯字典?在轉(zhuǎn)換字典格式?從一本詞典中篩選出四六級詞匯,制作背單詞軟件詞庫?
在編輯器中,繁瑣的查找替換工作、正則表達(dá)式不夠用了,怎么辦?每次重復(fù)的編輯操作是否可以保存起來以后直接使用?
其實(shí)你可以走得更遠(yuǎn),本文即將使用python進(jìn)行復(fù)雜的文本處理。(文科生不要灰心,我也是文科生)
python是一種腳本語言。腳本語言是什么?能干什么?
著名的腳本有javascript,它可實(shí)現(xiàn)諸多網(wǎng)頁特效。還有PHP,論壇搭建一般都用它,以PHP結(jié)尾的網(wǎng)頁就是。
近期的拙作pdbEditor、ZDicTool,都是用python寫的。
準(zhǔn)備
QUOTE:python,可以認(rèn)為它是一個沒有圖形界面的編輯器。得給它一些命令語句讓它執(zhí)行。
逐條輸入命令,它就會一條一條地執(zhí)行;也可把多條命令存成一個后綴為“.py”的文件,然后一起執(zhí)行。
所有#后面的文字都是注釋,給人看幫助理解的,程序并不執(zhí)行。
Linux中一般自帶python,在Windows中,可下載
python-2.6.msi
安裝。安裝后,py 后綴的文件可直接雙擊執(zhí)行。
運(yùn)行開始菜單中的python\IDLE,可以看到“>>>”提示符,這里可以逐條輸入執(zhí)行命令。
在py文件中右鍵選擇Edit with IDLE,或者使用ultraedit等編輯器,都可直接對py文件進(jìn)行編輯。
[color="blue"]簡單查找替換
一段文字,可長可短,長到一個大文件,短到一個空字符串?上扔谩=”把它們保存到一個變量中,方便多次查找、替換。
字符串也能像數(shù)字一樣進(jìn)行加法和乘法,是不是很直觀?
[Copy to clipboard]
CODE:word = 'I'
sep = ' /// '
mean = '我'
line = word + sep + mean # line的值就是 I /// 我
print line #在屏幕中輸出以便查看line的值
print mean * 10 #會輸出:我我我我我我我我我我
要進(jìn)行查找替換,可以使用replace(查找內(nèi)容,替換內(nèi)容)函數(shù)。
如果不想全部替換,只想把前N個符合條件的給替換掉,則可以再加上第三個參數(shù)N表示查找替換次數(shù)。
[Copy to clipboard]
CODE:line = line.replace(' /// ', '\t') #把line中的“ /// ”分隔符換成“\t”,仍然保存回line變量中,此時line值變?yōu)椤癐\t我”
new = 'aaa'.replace('a', 'A', 2) #把前兩個小a換成大A,第三個不動。
要在一段文字里查找某個詞,可以使用find函數(shù),找到它在這個詞中的位置(從0開始編號),若找不到則返回-1。
若要從后往前找,可以使用rfind函數(shù)。
[Copy to clipboard]
CODE:a='abcda'
b='bcd'
pos1= a.find(b) #返回bcd所在的位置,為1
pos2 = a.find('a') #'a'在a中第一次出現(xiàn)的位置,為0
pos2 = a.rfind('a') #從后往前找,'a'在a中第一次出現(xiàn)的位置,為4
pos3 = a.find('e') #返回e所在的位置,找不到,為-1
知道了位置(又叫索引,從左往右依次是0、1、2),就可從一大段文字中挖掘有用的內(nèi)容了。
[Copy to clipboard]
CODE:line[0]#line中第0個字符。
ine[-1]#line中最后一個字符。索引還可以是負(fù)數(shù),表示從右往左數(shù),依次為-1、-2、-3等。
#要獲得其中一部分字符,可以使用一個區(qū)間指定開始和結(jié)束位置,它包括開始索引字符,但不包括結(jié)束索引處的字符
line[0:10]#第0到9這十個字符,不包括第10個字符。
line[0:-1]#第0到-2這N-1個字符,不包括最后一個字符。
#當(dāng)開始索引為0時,可以省略
line[:10]#也就是line[0:10]
line[:-1]#也就是line[0:-1]
#當(dāng)要獲得包括最后一個字符在內(nèi)的一部分字符時,必須把結(jié)束索引省略
line[-10:]#獲得最后十個字符
line[1:]#獲得從1開始到最后的所有字符
help(str)可查詢更多字符串操作。
[color="blue"]高級查找替換:正則表達(dá)式
更復(fù)雜的查找、替換得求助于正則表達(dá)式(regular expression),在python中使用import re語句,就能用正則表達(dá)式了。
可以使用re.sub(正則表達(dá)式, 替換成字符, 源字符串)進(jìn)行查找替換:
[Copy to clipboard]
CODE:import re
s = re.sub('', '', s) #把s中所有之間的字符都替換成空字符,并保存回s
執(zhí)行import re語句后,再執(zhí)行help(re)可查詢更多正則表達(dá)式操作。
[color="blue"]讀寫文件
文件操作三步曲:打開、讀取或?qū)懭、關(guān)閉。
要打開一個文件,并讀取全部內(nèi)容:
[Copy to clipboard]
CODE:f=open('a.txt', 'r')#以讀(r)的方式打開文件a.txt,保存到f變量,然后就可以通過f進(jìn)行讀取、關(guān)閉等操作。
content=f.read()#把文件內(nèi)容全部讀取到content變量中,要讀取一行,可以使用readline函數(shù)
f.close()#關(guān)閉文件
要把content中的內(nèi)容寫入到文件b.txt中:
[Copy to clipboard]
CODE:f=open('b.txt', 'w') #以寫(w)的方式打開文件b.txt,保存到f變量,然后就可以通過f進(jìn)行寫入、關(guān)閉的操作。
f.write(content) #把content變量中的字符串全部寫入到文件中,寫完后不自動換行
f.close() #關(guān)閉文件
#或者
f=open('b.txt', 'w') #以寫(w)的方式打開文件b.txt,保存到f變量,然后就可以通過f進(jìn)行寫入、關(guān)閉的操作。
print >>f, content #也可以使用print語句把字符串寫入到文件中,寫完后自動換行
f.close() #關(guān)閉文件
help(file)可查詢更多文件操作。
[color="#0000ff"]排序、篩選、批處理
詞典是按字母順序排列的,那么怎樣排序呢?光靠一個字符串就難以實(shí)現(xiàn)了,而列表可保存多個字符串,可以進(jìn)行排序。
列表通常是使用[]表示的,可以使用sort函數(shù)對它進(jìn)行排序。下面兩句話就可以分別對a列表進(jìn)行升序、降序排列。
[Copy to clipboard]
CODE:a.sort()#正序
a.sort(reverse=True)#倒序
#如果不想改變原來的排列,可以使用sorted,獲得排好序的新列表。
b = sorted(a) #a不變,把排好序的a保存到b中
b = sorted(a, reverse=True) #降序排列
但是,怎么樣把這幾段文字弄到列表里呢?
[Copy to clipboard]
CODE:#可以直接建立
a=['bbb', 'ccc', 'aaa']
#也可先建一個空列表,然后通過append操作向其中逐步添加字符串。
a=[]#也可以使用a=list()建立一個空的列表
a.append('bbb')
a.append('ccc')
a.append('aaa')
#也可以通過文件中的readlines將所有的文件行讀入到一個列表中
f=open('a.txt', 'r') #以讀(r)的方式打開文件a.txt
a=f.readlines() #把文件內(nèi)容全部讀取到a變量中,每行為一個字符串(包括換行符\n)
f.close() #關(guān)閉文件
#還可以通過字符串的split函數(shù),將一個分割成多個字符串,保存到列表中。
s = 'bbb\nccc\naaa' #字符串
a = s.split('\n') #以\n分隔字符串s,保存到a列表
也許并不是每個元素都有用,可以使用filter(判斷函數(shù),列表)篩選出所有使得判斷函數(shù)的值為真的元素。
其中判斷函數(shù)一般使用lambda函數(shù),比如,要選出長度大于2的元素,函數(shù)可以寫成:lambda x: len(x)>2
[Copy to clipboard]
CODE:b = filter(lambda x: len(x)>2, a)#篩選出a中所有長度大于2的元素,并保存在b列表中
c = filter(lambda x: x[0]=='a', a)#篩選出a中以'a'開頭的元素,并保存在c列表中
也許元素的值并不滿足要求,可以使用map(處理函數(shù),列表)對列表中每個元素進(jìn)行處理。
[Copy to clipboard]
CODE:b = map(str.upper, a) #把a(bǔ)中每個元素都變成大寫,并保存在b中
b = map(lambda x:x[0], a) #把a(bǔ)中每個元素的第一個字符取出來,并保存在b中
b = map(lambda x:x[:x.find('\t')], a) #把a(bǔ)中每個元素\t前的所有字符取出來,并保存在b中
b = map(lambda x: x + '\n', a) #給每個元素末尾加個換行符,并保存在b中
怎么樣把處理后的字符串列表保存到文件中去呢?
[Copy to clipboard]
CODE:#若每個元素最后都有換行符\n,用readlines讀出來的列表就是這樣,它可以用writelines保存到文件中去。
f=open('b.txt', 'w') #以寫(w)的方式打開文件b.txt
f.writelines(a) #把a(bǔ)列表中的所有字符串全部寫入到文件中
f.close() #關(guān)閉文件
#若行末沒有換行符,則可以先使用map給每個元素加上換行符,再使用writelines寫入文件
f=open('b.txt', 'w') #以寫(w)的方式打開文件b.txt
a = map(lambda x: x + '\n', a) #給每個元素末尾加個換行符
f.writelines(a) #把a(bǔ)列表中的所有字符串全部寫入到文件中,
f.close() #關(guān)閉文件
#上述操作也許效率不高,可使用“\n”先將列表串聯(lián)成一個大字符串,跟split的操作剛好相反
f=open('b.txt', 'w')#以寫(w)的方式打開文件b.txt
s='\n'.join(a) #使用\n將a連接成一個字符串
f.write(s) #把字符串s寫入到文件中
f.close() #關(guān)閉文件
#還可使用print寫入文件,每次寫入一個元素,存成一行,自動添加換行符
f=open('b.txt', 'w') # 以寫(w)的方式打開文件b.txt
for element in a: #對a中每個元素進(jìn)行處理,每次取出一個元素保存至element中
print >>f, element #每次寫入一行,注意縮進(jìn),這句是for循環(huán)中的,比其他語句低一個層次
f.close() #關(guān)閉文件,這句在for循環(huán)外面,所以沒有縮進(jìn)
help(list)可查詢更多列表操作。
[color="#0000ff"]比較文件、刪除重復(fù)
文件經(jīng)過多次編輯操作,可能會有重復(fù)的,列表就無能無力了,這時可以使用集合,因?yàn)榧现袥]有重復(fù)元素。
比如要把文件a.txt中的所有重復(fù)的行去掉,并按順序輸入到b.txt中
[Copy to clipboard]
CODE:f=open('a.txt', 'r')
lines=f.readlines()#讀取a中的所有行
f.close()
f=open('b.txt', 'w')
lines_set=set(lines) #使用set函數(shù)將所有行變成集合
lines=list(lines_set) #使用list函數(shù)將集合變成列表進(jìn)行排序
lines.sort() #對lines進(jìn)行升序排列
f.writelines(lines)
f.close()
#也許看起來很復(fù)雜,你可以使用下面的一句話實(shí)現(xiàn)所有過程
open('b.txt', 'w').writelines(sorted(set(open('a.txt', 'r').readlines())))
集合可以進(jìn)行交(&)并(|)差(-)等操作,比如,要比較cet4.txt和cet6.txt兩個文件,獲得六級特有詞匯:
[Copy to clipboard]
CODE:f=open('cet4.txt') #默認(rèn)為打開模式
cet4=f.readlines()
f.close()
f=open('cet6.txt')
cet6=f.readlines()
f.close()
seta=set(cet6)
setb=set(cet4)
setc=seta-setb#對seta、setb取差集,即只在seta中而未在setb中出現(xiàn)的元素所組成的集合。
new_cet6=list(setc) #把setc變成列表,方便輸出到文本
f=open('new_cet6.txt', 'w') #寫入文件
f.writelines(new_cet6) #寫入六級特有詞匯
f.close()
help(set)可查詢到更多的集合操作。
[color="#0000ff"]查詢單詞、篩選詞表
字典dict這種結(jié)構(gòu)在做詞典時比較有用,相當(dāng)于兩組列表:保存單詞的鍵列表(不可重復(fù))、保存解釋的值列表。
字典一般用{}表示,鍵值間用“:”分隔,如:d={'I':'我', 'you':'你'}。如果要查詢you,可通過d['you']獲得you的解釋。
直接建立字典規(guī)模不會太大,通常從一定格式的文件(比如每行格式為:詞語\t解釋)中創(chuàng)建,
[Copy to clipboard]
CODE:d = dict()#建立一個空字典,也可使用{}建立。
f = open('a.txt', 'r')
for line in f: #每次從f中讀入一行
line=line.rstrip('\n')#去除行尾的換行符
word, mean = line.split('\t', 1)#將line用\t進(jìn)行分割,最多分一次變成兩塊,保存到word和mean中去
d[word]=mean
f.close()
若要將建好的字典d按序輸出文件中,可使用iteritems取出所有的鍵和值,對它進(jìn)行排序,然后按序取出所有的值
[Copy to clipboard]
CODE:f = open('a.txt', 'w')
for word, mean in sorted(d.itertems()):
print >>f, word+'\t'+mean #輸出時使用\t分隔單詞和解釋,然后換行
f.close()
若只有輸出d中部分詞和解釋制作詞典,比如只輸出cet4_words列表中的詞:
[Copy to clipboard]
CODE:cet4_words = ['a', 'the']
cet4_words.sort() #對cet4_words進(jìn)行排序
f = open('a.txt', 'w')
for word in sorted(cet4_words):
print >>f, word+'\t'+d[word] #輸出時使用\t分隔單詞和解釋,然后換行
f.close()
help(dict)可查詢更多字典操作。
本文來自ChinaUnix博客,如果查看原文請點(diǎn):http://blog.chinaunix.net/u2/78998/showart_1678087.html |
|