掌上百科 - PDAWIKI

 找回密码
 免费注册

QQ登录

只需一步,快速开始

查看: 2239|回复: 10

[教程] 【实验室】用NLTK处理词典文本的使用笔记

[复制链接]

该用户从未签到

发表于 2016-7-14 11:44:55 | 显示全部楼层 |阅读模式
本帖最后由 fnaviwwo1 于 2016-7-15 12:06 编辑 : z; B5 L% U4 v' K
$ G. z" _- V+ L  e
CHANGELOG
  q- k; n+ r, t+ [20160714] 第一版,为句子建立单词索引。
$ c# X# d9 g0 p! r! i+ [20160715] 引入词性标注模块,改进单词提取结果 2 W. J' r) K* o8 w
- - - -
& {0 j3 K# Z7 ]9 s. H& [2 U$ _+ J+ E; g& E1 E0 C9 j5 U9 v
受到这个帖子的启发。8 A9 N5 |  i& G2 G  T4 ^/ G

$ }4 T. P9 L3 y* a$ iNLTK是个非常好用的自然语言文本的处理工具,用来处理文本编纂词典非常有帮助。
. x' A/ b* G, b) ?% }5 c! c
( ]3 n" I% T) O3 |以下是一些使用时记录的笔记。
" k4 e* E. v( \) I( Q! ^9 [" Y3 n3 w' h0 @5 K( i6 i" Y- K7 a+ y
先导入和创建用到的东西8 n( R7 r% c- h( s& B

  1. . j& {% T3 k* ?# R$ h$ P- I
  2. import nltk
    3 a3 f8 l" N0 D- }  h/ U8 @  _
  3. from nltk.tokenize import sent_tokenize, word_tokenize3 G4 A0 i( o+ A, M+ X
  4. from nltk.corpus import stopwords9 n4 Q. r1 o7 m1 b! y+ f
  5. from nltk.corpus import wordnet as wn
    7 R+ H# m. s) E$ S0 v" n, s7 z' [
  6. from collections import defaultdict
    * `. ?( w1 f/ U3 L' x
  7. sw = set(stopwords.words('english'))" O$ H: i# G" u' x
复制代码
$ _2 Q1 ^# {+ X8 e, T- x) z' ^2 r
! ]1 E' G" h) s) F3 N
任务一:为句子建立单词索引
3 X  [, H8 @& s8 u5 {7 r0 \2 g" j9 T. d4 h! q: c" _% }" H, w
(这段代码有问题,直接跳过看后面的改进好了。)
/ Q/ B" Z! r) ?% Q: M: V0 a! I
+ m: p2 S' V5 y# s4 ?  c; e4 }先随便找了一段文字
: o9 s$ T2 i% O1 y0 p$ b2 u; b
  1. s = '''
    " e; n; w6 a% ^/ t) `
  2. Donald Trump is insisting that aides stick to confidentiality agreements so much so that he is suing a former campaign consultant for $10 million, his lawyer said.
    7 {* C: k7 ~+ M- r
  3. 4 T7 e& P: E: v$ U4 Z+ F1 P) q
  4. "He's violated his agreement and you know we have taken swift and appropriate action," Alan Garten, executive vice president and general counsel at The Trump Organization, told USA TODAY. "We intend to pursue this to the very end."9 ^; ?0 C1 M3 s  c8 c9 m
  5. / K% P2 J8 Z% ?+ F' }
  6. Court documents obtained by the Associated Press indicate Sam Nunberg has been accused by Trump of leaking confidential information to reporters in violation of his non-disclosure agreement. Nunberg, in response, accuses the Republican candidate of "a misguided attempt to cover up media coverage of an apparent affair" between senior campaign staffers./ }) S) _6 S4 t$ G, W
  7. '''.strip()
复制代码
/ J8 o2 w, I7 b$ @
分句:
9 ^0 H8 V' H3 f/ G( l
  1. ss = sent_tokenize(s)
    ! Z. [, v: u- T0 D% z
  2. print "有%d个句子。"%len(ss)
复制代码
" B$ O; Z4 g" L  Q
建立索引
. G$ U) t7 }$ ]/ V, C0 \
  1. 5 C0 P7 X4 v) n  G* q
  2. find_words = (lambda s:
    ! P8 u8 h$ J2 R
  3.     filter(lambda x:x.isalpha() and x.lower() not in sw,4 C2 Z$ s8 K8 ^6 u6 u
  4.            map(lambda x:wn.morphy(x) or x, word_tokenize(s))))* ]4 i+ Q4 |: ]* ^5 t* |
  5. kv = ((w,i) for i,s in enumerate(ss) for w in find_words(s))
    / S* c7 Z! ~$ Y+ x$ P" ^; \
  6. kvl = defaultdict(list)
    " X7 {, K1 h+ u( E  F$ h. O
  7. for k,v in kv:0 |3 @9 V, L" u* A% E! M- z1 L
  8.     kvl[k].append(v)
    * Y! J! `, C) B1 ]
复制代码
1 N6 d5 }% Y( C
看一下结果:
+ E4 `; W$ q, a2 K8 l% d# C: Z( r* J" W
  1. $ ^) R" T8 j/ A# B
  2. for k in sorted(kvl.keys(),key=lambda x:x.lower()):
    : u9 n1 I: e; W+ M+ }8 t6 O% {
  3.     print u"单词 %s 在第 %s 句中出现"%(k,','.join(map(lambda x:str(x+1),kvl[k])))7 H8 `0 z: ^9 ]( l+ D
复制代码

; }7 t; O2 e2 \- o+ ?) |得到:- K0 M, P6 U6 F
单词 accuse 在第 5 句中出现
: U% }1 g3 K. `3 L9 c; Y单词 accused 在第 4 句中出现
  _; I4 N3 M0 M% e9 d7 q! t# q单词 action 在第 2 句中出现: ^" r2 ]5 O5 U8 `4 @6 A5 w# L/ J; W
单词 affair 在第 5 句中出现
& c5 V' U( z' [' j: G单词 agreement 在第 1,2,4 句中出现
% m; T* H6 Y3 D9 d0 s单词 aides 在第 1 句中出现4 W1 a, m" c- d
单词 Alan 在第 2 句中出现5 P4 M6 h/ V0 @6 y/ x
单词 apparent 在第 5 句中出现; U& I% h) z7 m& X) P/ U. G
单词 appropriate 在第 2 句中出现, t2 V0 K* h) s2 T4 k
单词 Associated 在第 4 句中出现
# P9 r8 D  D3 ]8 a* g单词 attempt 在第 5 句中出现; ]+ _+ z' c# N
单词 campaign 在第 1,5 句中出现
5 `/ S7 N2 a' f单词 candidate 在第 5 句中出现  h2 k% }8 _" X7 ?
单词 confidential 在第 4 句中出现
1 H7 {& l$ X; i" f) L6 Q! [单词 confidentiality 在第 1 句中出现7 N* |5 u' u0 R0 D  O8 T7 H) J* m
单词 consultant 在第 1 句中出现
0 k# L# \/ ?6 f  V  }单词 counsel 在第 2 句中出现
/ O4 c8 t& T- ~3 e单词 Court 在第 4 句中出现
& C7 M( K: a& ^9 }/ j) W9 U5 R+ Z单词 cover 在第 5 句中出现: ^; o$ j, p# R! G. M5 `$ B
单词 coverage 在第 5 句中出现
. I, Z% }* E% A: r  L单词 document 在第 4 句中出现
  B9 U) k5 C) \; a单词 Donald 在第 1 句中出现
) v; b) F9 i( Z0 W: g$ p单词 end 在第 3 句中出现
$ A  \) D' k* T; @7 v8 V( u- n4 ]单词 executive 在第 2 句中出现
; H$ H5 }1 A2 Z, w: p单词 former 在第 1 句中出现& ^4 i  Q' w7 h6 ?; o
单词 Garten 在第 2 句中出现
1 `* I5 c1 O0 b7 H, W  X; L单词 general 在第 2 句中出现
5 f. ]5 X8 `) a5 U; U单词 ha 在第 4 句中出现
/ M5 z' d) V9 X! `; U+ T单词 indicate 在第 4 句中出现: u" ~: q7 \" X$ O
单词 information 在第 4 句中出现
7 {6 a' R: M" D8 [& t单词 insisting 在第 1 句中出现
) ~8 h! |. Y  b9 |单词 intend 在第 3 句中出现. m: z1 x- g9 ]  E  k
单词 know 在第 2 句中出现
: q# _$ d- S6 O# }4 H1 t单词 lawyer 在第 1 句中出现) [1 f; {" |  B" `* U) f3 p
单词 leak 在第 4 句中出现
8 y4 o9 B$ ~9 G6 J9 d1 _单词 medium 在第 5 句中出现
% e8 I( ]! t* K! Z" ~& E! o3 _1 k单词 million 在第 1 句中出现/ E: s  n, T2 J7 [8 {
单词 misguide 在第 5 句中出现
8 w7 H7 \' e5 I: t单词 much 在第 1 句中出现( v% t" \1 P) A/ _6 B; F8 m7 y
单词 Nunberg 在第 4,5 句中出现
+ a; @- {) ]7 m! E' b单词 obtain 在第 4 句中出现
: Y2 c4 N# C) I* ~  y单词 Organization 在第 2 句中出现0 z! Q& |- v1 X% |- G
单词 president 在第 2 句中出现
) m( f8 M& c2 w7 }8 U( [! j% b单词 Press 在第 4 句中出现
3 L6 q7 `4 o$ \! Z2 f1 H单词 pursue 在第 3 句中出现
, c8 T8 o5 B7 O% _0 X单词 reporter 在第 4 句中出现
& ]1 s8 r# E: u, B+ y. i# A$ d单词 Republican 在第 5 句中出现  U- V% l6 I8 D# t6 n7 u9 [9 @
单词 response 在第 5 句中出现
  h/ r* o7 W1 V0 i2 {单词 Sam 在第 4 句中出现& E* z! r7 r  t5 V/ f+ Z
单词 say 在第 1 句中出现
) o$ O7 a* h" _& a5 `2 h单词 senior 在第 5 句中出现
6 A) e/ V2 F; h9 J" s1 L/ B单词 staffer 在第 5 句中出现
9 j) I& o9 Q3 |单词 stick 在第 1 句中出现+ [$ Y5 b& Q; k/ ]0 `/ V! u
单词 sue 在第 1 句中出现  S7 T$ x! ~/ i
单词 swift 在第 2 句中出现
* ]  K6 Z9 v; K' h) Q( x5 z2 E单词 take 在第 2 句中出现
# i; k. s: c5 g) Y单词 tell 在第 2 句中出现
& a9 L' b" {+ E% c6 s9 ~+ |单词 TODAY 在第 2 句中出现
6 k3 I$ y* z% X' k7 t/ l单词 Trump 在第 1,2,4 句中出现
4 j( j' L$ s6 E: n单词 USA 在第 2 句中出现+ K4 a9 p: o& Q7 e8 G& [
单词 vice 在第 2 句中出现
; ~3 D5 w5 P, T- [9 d0 U' G单词 violate 在第 2 句中出现
8 X0 P8 |& m/ p0 k单词 violation 在第 4 句中出现

# C. M6 z9 b) Q; F; A
) R* O4 P8 I! V4 \* P/ Y还是有点问题啊,比如专有名词和大小写还有派生词的问题,等我再修改一下。
- a5 X" \6 ?( S& {4 i; m5 C4 S/ q: k0 R
----$ f3 K: ?2 p7 M9 h
发觉NLTK内建数据的服务器老是连不上,大概要挂代理,还要耽误很多时间,有点难受。。。
* ^$ n) }" Y6 w) a3 g
$ h2 u7 w* i& {/ E5 Z7 c6 }  j
. P8 f: U) T5 A6 Z' S# ~3 N
- z% n- r( U5 T' w' k$ y( F- [6 F* V  w
! p2 b( M( U. [5 e3 _5 n8 B改进版 1
9 ]% w: x" _% h5 ?) ]; S; n% n
9 k9 b. Q4 K1 F$ F0 {$ c加入了NLTK自带的词性标注功能,虽然得到的词性标注只是近似结果,做以下用途还是略有效果的:! b- ~0 v6 E: i( i! b  |  s0 b: F9 P
  1. 过滤专有名词. Z% s5 s/ O% o+ H4 B
  2. 根据词性进行词形变换8 O0 N# ~. [( @7 w# {
0 y$ T  o% D( _
  1. ss = sent_tokenize(s)
    + i0 p% C- g6 G/ Z

  2. % `; f: H7 {& B5 ^: a9 l2 R5 S; |1 v
  3. _SW = set(stopwords.words('english'))|{'much'}- g& R' L0 H" s- `. y, `: `4 P
  4. _P = {'N':wn.NOUN,'V':wn.VERB,'J':wn.ADJ,'R':wn.ADV}! p% O0 ?4 G( M6 q1 W/ y6 q
  5. def _name(word,pos):# U, q4 @7 g1 f2 x8 @8 \
  6.     word1 = word.lower()
      _" F; ?( H5 C7 ], j; V2 @
  7.     pos = _P.get(pos[0],None)
    8 u' U) Z( m* n) {" p9 r$ Z: b
  8.     x = wn.morphy(word1,pos) or wn.morphy(word1,None)7 s  u% q  a- S/ x8 j
  9.     if x is None: return
    / y4 u, k; w( i2 J# n
  10.     if word[0].islower(): return x
    / \% ~! \# A( Q' z: X# @
  11.     x = wn.lemmas(x,pos)
    ; f! c+ b& d! ^, y" Q3 F
  12.     if x: return x[0].name()/ `, F2 P3 V6 U+ U
  13. def find_words(sent):
    3 U9 s/ a: b& E0 B3 U
  14.     tags = nltk.pos_tag(nltk.word_tokenize(sent))
    8 v$ ~8 u$ p; x
  15.     morphy = lambda tags:filter(
    0 O  H* X8 K# w, G2 v7 ?& z3 m( E
  16.         lambda (x,_):x and x.isalpha() and x.lower() not in _SW,
    / `3 j1 N9 ~! M; p. V2 ~3 f
  17.         [(_name(word,pos),word) for (word,pos) in tags if pos!='NNP'])3 e2 m" @7 V( t, B& K
  18.     print "=== DEBUG: ===\n",sent,"\n",tags,"\n",map(lambda x:x[0],morphy(tags))
    3 W1 q/ }6 w$ k
  19.     return morphy(tags)
    ! P9 I: c3 P0 v8 m3 Y
  20. def gen_dict():2 O3 ^( Q2 W- A$ A& e4 h; D( P7 X
  21.     kv = [(w,i) for i,s in enumerate(ss) for w,_ in find_words(s)]
    0 R9 o+ P8 t; D; f. p+ l
  22.     kvl = defaultdict(list)- l! x' m# v3 j. I/ d1 n
  23.     for k,v in kv:
    9 U2 P9 n: [% H7 z: z+ B
  24.         kvl[k].append(v)
    . U$ J8 {! k* g
  25.     return kvl# |5 `' }7 r% C% \; J6 F& M" g3 m
  26. kvl = gen_dict()6 l) K$ |! A" O: Z- S* x, F
  27. for k in sorted(kvl.keys(),key=lambda x:x.lower()):! b- S' O4 S) E& Y+ X# q8 f. A" o
  28.     print u"单词 %s 在第 %s 句中出现"%(k,','.join(map(lambda x:str(x+1),kvl[k])))
复制代码
2 @) I, j! X% P6 w. b" c
' c& `. M! @6 m4 b/ Y3 q( }
得到
1 E1 Z. r, s) c. X
单词 accuse 在第 4,5 句中出现
" C3 {2 ?4 Y2 C2 K4 }6 \0 {) ~单词 action 在第 2 句中出现0 {3 l. Q/ A9 H, P7 }5 l6 R( R0 g
单词 affair 在第 5 句中出现; O) M* N) e& t  [% I1 |
单词 agreement 在第 1,2,4 句中出现4 A; n* T  v4 @: u1 K$ u6 z/ v
单词 aides 在第 1 句中出现
. ]! o9 e1 V5 ^单词 apparent 在第 5 句中出现+ G, B. d- _/ w5 Z" G+ D4 H$ R
单词 appropriate 在第 2 句中出现) |3 u3 l1 m; K( p7 U
单词 attempt 在第 5 句中出现
- B: H8 E% G  I单词 campaign 在第 1,5 句中出现  H  L9 }4 ]6 s; P0 S6 H/ g
单词 candidate 在第 5 句中出现0 n- i& X/ S- o: Z# a4 d
单词 confidential 在第 4 句中出现; i, S! o8 J0 X" N' C6 Z
单词 confidentiality 在第 1 句中出现
- x$ x4 Y) }4 G- X1 C单词 consultant 在第 1 句中出现
, `: e3 i4 L* S: V8 m/ q单词 counsel 在第 2 句中出现
/ w, F) K. j+ m/ j1 i3 f单词 cover 在第 5 句中出现+ G: F% h, T' V/ |1 p. z7 ]
单词 coverage 在第 5 句中出现
  p9 d0 g& g  F5 m. _" Z单词 document 在第 4 句中出现% ?, g, H# {% g7 ]0 P3 |% y* J
单词 end 在第 3 句中出现
, a* B' U. L, Y8 v+ E单词 executive 在第 2 句中出现
/ b( M( j+ ]5 K. ]单词 former 在第 1 句中出现
* ?/ N) o* @" d2 d6 a单词 general 在第 2 句中出现( z+ R6 N' K7 P  x5 H0 `$ ?
单词 indicate 在第 4 句中出现
5 q* o" o! {3 I4 U# V0 c/ K单词 information 在第 4 句中出现+ o( c$ S. G3 A# o" Q0 y
单词 insist 在第 1 句中出现
, h( X5 h) |7 g( i单词 intend 在第 3 句中出现3 V( o6 M# k* u! r  D4 k  T6 j1 l
单词 know 在第 2 句中出现- t' _9 |( p9 g7 O7 D7 r6 \# g/ R
单词 lawyer 在第 1 句中出现. Z5 w; W6 |. y; Y
单词 leak 在第 4 句中出现
6 ?. N6 N& @6 ~0 U单词 medium 在第 5 句中出现- J. i5 E8 Q4 y/ z3 B0 c3 L
单词 million 在第 1 句中出现1 E7 r& `% p( R" j* g; P: \
单词 misguided 在第 5 句中出现) v, B7 \6 G' C; @4 g% K$ F
单词 obtain 在第 4 句中出现( C7 c% f* y; Y4 ~4 D1 ~
单词 president 在第 2 句中出现
9 k3 u# @6 H: H- |# I  n单词 pursue 在第 3 句中出现' l8 x' X7 d8 d' a' V4 w. a  j, C
单词 reporter 在第 4 句中出现$ R) [0 C2 N6 T% L5 Y% e
单词 response 在第 5 句中出现
0 A( H/ R* P/ e) x单词 say 在第 1 句中出现
6 {. e4 t# |- \! N单词 senior 在第 5 句中出现
2 s% t% t1 e6 u: y: p# F. Q( K单词 staffer 在第 5 句中出现
5 S7 O4 @, c" F3 v) n0 \单词 stick 在第 1 句中出现. H2 X5 ?5 B( a& ^0 f
单词 sue 在第 1 句中出现4 P" S3 N% }* Z/ y
单词 swift 在第 2 句中出现
  v- ~9 I! w) z单词 take 在第 2 句中出现
6 e4 w9 N& {' E; Q5 s6 ^6 y% g! Q单词 tell 在第 2 句中出现
% s+ L! r' I: {( }6 D5 D' b单词 vice 在第 2 句中出现% X, X, u/ l4 T/ C+ o" y4 a. f
单词 violate 在第 2 句中出现: O2 i/ ~+ K6 b! R  b
单词 violation 在第 4 句中出现

. f( }" v) M5 z8 L. P7 Z* x1 a$ y. A  u. I8 ~
看出来,结果比前面第一个版本有非常好的进步。

本帖被以下淘专辑推荐:

该用户从未签到

发表于 2016-7-14 12:41:53 | 显示全部楼层
本帖最后由 lxchen2001 于 2016-7-14 15:59 编辑
) I6 R$ T( k/ `
) u% i# X5 H% C专有名词可以用 Named Entity来解决,网上看到的,但我还没去用过' H4 E' H) |; W7 Q) [! g. ?1 v

. `4 S- p' b7 D6 p/ r/ ]! X+ \  ~用lemmatize 可以找到单词原型

该用户从未签到

 楼主| 发表于 2016-7-14 13:01:24 | 显示全部楼层
本帖最后由 fnaviwwo1 于 2016-7-14 13:05 编辑 , o7 H1 `1 @% \
lxchen2001 发表于 2016-7-14 12:41
/ r# M8 X4 i  n- {. t" j5 c4 f专有名词可以用 Name Entity来解决,网上看到的,但我还没去用过  J1 s; H) v# K; k# x! J" h! e

0 w, a9 K- s! h2 x, j5 u. n3 g用lemmatize 可以找到单词原型

3 \, ?, N( f; V- ^4 w7 }
$ j$ e. V5 m# I) `: E2 _. t) {看来又得拜乔姆斯基大神了。。。字母->词法->语法->语义是不同层面的东西。: P1 v, m( }0 R* X# q  f) f
单词形式在词法层面解决不了,而lemmatize是词法上的功能,它分不出-ing结尾是做动词还是形容词。
7 O$ n0 d* d. |4 R
! J- F& z% s! n6 H- t8 B. g4 E让我再看看还有什么能用的。(这网络想用一个NLTK模块真是痛苦,它非要联网加载。。。)
) {. {$ y2 N" p6 h0 \7 r
9 b0 }5 Y; J$ w+ v专有名词要处理句法的问题之后,教程的这章节我还没看到。。。

该用户从未签到

发表于 2016-7-14 13:05:22 | 显示全部楼层
本帖最后由 lxchen2001 于 2016-7-14 13:14 编辑
7 \( u5 y1 g8 W1 |7 L4 }; M8 q" }# z9 k5 Z1 Z8 k
明白stem的用法了 可以容易的在原句中找到派生词。. D# f0 e/ i; x' A

8 `& Q. f! [! l+ ^. ?你的Python很熟练 学习了3 y; W2 }& ~, U3 ?. n7 y3 u, r

6 F/ I, x( W. {* R请教 怎么在例句中给找到的词加个html标签, 比如<em>action</em> 和  <em>actions</em>

点评

re.sub(r"\b(action)\b",'<em>\\1</em>',"The government is taking emergency action to deal with a housing crisis.")  发表于 2016-7-14 13:17

该用户从未签到

发表于 2016-7-14 13:20:32 | 显示全部楼层
lxchen2001 发表于 2016-7-14 13:051 l4 Q* _- s1 Z1 R, o% T' G
明白stem的用法了 可以容易的在原句中找到派生词。# Z& t# K9 y7 M+ G) x

" u8 P, Z  [# w你的Python很熟练 学习了

9 r, ~/ `2 D" E/ g1 w谢谢   真快

该用户从未签到

发表于 2016-7-14 16:12:01 | 显示全部楼层
本帖最后由 lxchen2001 于 2016-7-14 16:14 编辑 " i0 e$ m) `+ b) A
' I: L. }1 z9 ~( x
楼主 要不您建个QQ群或者组  方便讨论?
) J; G1 L; \2 h1 r/ I
3 p! c/ t& x9 E; l+ @, M如果我把nltk_data文件夹发给你   是不是你就不用下载了?

点评

好啊,我在mdict那个群里,拉一下。  发表于 2016-7-14 21:06

该用户从未签到

 楼主| 发表于 2016-7-14 21:04:45 | 显示全部楼层
lxchen2001 发表于 2016-7-14 13:050 b: u- X* ^  v$ ]7 D/ y
明白stem的用法了 可以容易的在原句中找到派生词。0 I0 ?  ^# H' e) i) h- d

! d# P: k1 C' I0 h( y9 H你的Python很熟练 学习了
* ?) V( o3 Y, x+ t# K! f6 q8 e
stem的用途是建立索引,比如让相关衍生词可以用一个字符串索引,然后搜索的时候输入的字也转到这个字符串上,不过出于效率考虑得到的这个字库串本身是没有意义的,所以不能充当词典词条。
6 g$ S& ~  K: l/ B, [看了一下goldendict的代码,它是用hunspell这个库来解决输入的词条的变形的,效果正符合需要。; @" Y% X" Q1 ]6 q- B, ]5 t6 M

' c9 o- u% w+ n  k$ u6 j& Q  }专有名词准备加tag把NNP过滤掉,有了词性标注大概在转词形的时候,可以作为依据了。1 H3 I2 `5 A- W, u
7 a5 Y- b& ]: v$ `
我才意识到,nltk的好多函数都是近似结果,并不一定准确。

该用户从未签到

 楼主| 发表于 2016-7-15 17:03:08 | 显示全部楼层
把脚本处理一下实际一些文本试验一下效果 8 z$ M! p3 H3 g/ s0 ^1 L* j4 D
整理了一下《傲慢与偏见》中出现两次及以上的单词【附工具】
  • TA的每日心情

    2020-10-22 07:38
  • 签到天数: 78 天

    [LV.6]常住居民II

    发表于 2017-7-6 12:00:10 | 显示全部楼层
    楼主真棒!向你学习:)
    您需要登录后才可以回帖 登录 | 免费注册

    本版积分规则

    小黑屋|手机版|Archiver|PDAWIKI |网站地图

    GMT+8, 2024-4-26 08:51 , Processed in 0.070072 second(s), 15 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2023, Tencent Cloud.

    快速回复 返回顶部 返回列表