数学建模社区-数学中国

标题: Python爬虫 正则表达式应用详解 [打印本页]

作者: 杨利霞    时间: 2020-3-30 11:00
标题: Python爬虫 正则表达式应用详解

$ ^( t4 B  q4 a; Y' i' H3 Z1 dPython爬虫 正则表达式应用详解+ e- t$ f. O! c7 ?2 }# U3 ^3 S

/ C1 v% ^' J1 D% ^学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。* A9 I! t4 F, f  v# S. S

2 ~4 N4 J& [4 y. W; x—— 正则表达式应用详解 ——3 }9 p' I4 ?  Z3 u, C5 R

6 Y- ~* P/ Y) g+ X# k4 z文章目录" g. y2 N- D1 [- g5 Z- k8 h6 ?/ z' x2 D

5 _. o9 Y; v: c7 U( j. rPython爬虫(二十一)
( V- }2 [3 X1 Z4 j2 `3 ~: K—— 正则表达式应用详解 ——3 j0 U  j$ f# u$ R1 _: @
1. 简介) i. s6 k2 w" @; |; @: z( I
2. 语法+ }9 p6 x" |. r, o, I5 L" Q* T
3. 部分元字符应用详解
/ U: ^4 g  v* W, V7 V* P^' j% @6 X2 n. [. o6 Q& i
$
3 t, o9 h2 I9 k3 u' L\A4 D/ f( D, d3 S
\b2 E4 q3 e# c6 e0 {8 O7 V
\B$ K" ^0 {2 b3 s$ o
3. 正则表达式实例
/ ^4 [. ]# t5 y相关文章:' ]. Q* \) h7 M+ x
1.Python的Re库应用详解(正则表达式的库)1 c3 N* C- q% X0 W' v* O
2.Python的Re库与正则表达式的细节解析(正则表达式的库)
6 s+ Z/ v% |! w' J4 K# X. [, R
8 f1 H! p+ E7 {) r- j# @6 P1. 简介
) i2 v, Q4 g3 ~8 A3 }$ H- w8 _
- Q' L# E$ ]3 c9 h* _2 a正则表达式:regular expression,也称regex,简称 RE8 s, \. |3 {- Y# N6 i; D
5 D- P/ t" C9 F3 ?
正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。! w9 P1 N* B8 n3 g
, h, U9 t2 W9 r" N1 p' G3 \+ W6 v0 Z
正则表达式是用来简洁表达一组字符串的表达式
% b. j8 q9 v1 P( T6 n7 T/ L( R) f# k5 g' y  @
通用的字符串表达框架, F- v9 E8 y  P4 j) e5 o
* q0 I. j4 k/ A1 n
简洁表达一组字符串的表达式" L9 K9 J" ?: H
- S% q; O2 R  f+ o/ t
针对字符串表达“简洁”和“特征”思想的工具3 ]/ W) ~- S+ m0 }& {+ i8 j1 c; t

- x- A5 q# ], f) p判断某字符串的特征归属
) o: U7 n. \' v! H# ~- c- x" ?" Z' k8 |; a
正则表达式在文本处理中十分常用
/ Q# e' n  p8 g4 ~0 T2 \: B9 K7 A& M6 l: C* O3 P: |
表达文本类型的特征(病毒、入侵等)
% ?/ ]# q( V/ W" x( Y
) u5 M/ U) D- g; F/ V: S同时查找或替换一组字符串7 {9 e" m8 x9 j

' w0 u7 n, `$ L6 T  }) s匹配字符串的全部或部分
* o, t- e" S& Q" Y6 o1 L1 W, L! A: w! b% p# |2 e2 G: k
正则表达式的使用
: G. E/ S! {: o  L/ P! I
2 y: G7 X' j5 j" z- D8 R0 D" D编译:将符合正则表达式语法的字符串转换成正则式表达特征( e) `2 e$ `9 i( z: e7 t, v
' F9 U. [% h$ f

+ @+ _$ m. v  I2. 语法/ B0 l3 E' n$ l. T8 W) z
" U  L$ o1 |8 m" K, U
正则表达式语法由字符和操作符构成
6 x, F& w: v5 I( G/ [7 B
: b2 d( c6 U  {2 ^: i& N. H& M" a% M有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。- f- E4 ?, |# W  Z* M2 \
元字符包括:. ^ $ * + ? { } [ ] \ | ( ), _+ ^4 E! s- i9 ?- o
正则表达式的常用操作符
9 Z: I1 a8 [# j" G& C5 h9 A, i在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
; }! |! U2 y# _2 T1 @操作符        说明        实例
9 [% }: |6 x6 ?5 m+ y.        表示任何单个字符(除换行符) 【注1】        % r: l% c5 j/ c4 |
[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
1 c3 e  [- B+ ]/ o6 ?, z[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符
( C6 i7 V+ u3 `, p*        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等; H* Y- O) J) W- m# j+ u
+        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等2 ~% W$ J- ]# C! Q0 I9 G
?        前一个字符0次或1次扩展        abc?表示 ab、abc
7 A. T" e* p& S$ G& Y|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def9 q7 e/ u" M$ h% o$ Q: a- u6 r
{m}        扩展前一个字符m次        ab{2}c 表示 abbc6 D+ M9 ]- P) D8 `+ \1 K$ e: h
{m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc
1 |* q$ @/ K' f$ Y6 @# H/ _6 \^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头
, o0 ]2 [$ v' p! o$        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾) ~" F+ m9 U/ d/ Y% |$ `# u& H. ~! J
( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def& }& P4 b% L# o  y/ ~
\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u) i  D) T) V3 ?) v# r# x" i
\d        匹配十进制数字,等价于[0--9]       
5 [; t( L9 P7 ]2 Y  r9 Z+ [\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]        ' U6 |! a7 ~. ?# S; e  v; q
\s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
6 k; k9 f1 }! F; s" }; q\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]        ( c: Y' z+ @& h, y, U6 X4 B
\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
6 h$ f8 |9 f* }1 ]! a\W        于 \w 相反       
9 a: B5 b, M; O7 j- U% N' t\b        匹配单词的开始或结束        2 c/ W( L5 w$ i2 q  e3 ^
\B        与 \b 相反        " ?9 m4 }9 J  q- d* G* L& q7 ?
\Z        只匹配字符串的结束位置。        . U. e7 V3 h% I% q
【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。, h1 M, f! d( P  I. F
5 n$ a9 D# Y( U" {
【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;! s/ @" a1 Q, a0 j5 b& D

8 \5 S& d1 L- z% f* d& H: ~1 Q【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。6 b$ t+ j& L$ c" n( V6 w
: d" E2 E/ i1 y( U
【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。
) R& V  ^( [9 E. p9 L  t
# J9 |& r; J, m0 q" n9 y" h, k【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。$ \+ {' T2 c9 {$ J- w

- X) g2 o! D+ g& A* Q+ v5 D6 u- {% @% G3. 部分元字符应用详解1 A1 n2 ^$ H0 q* s; l# R' i
1 g9 A. o; t/ R0 N7 H" m5 N
^7 z& x2 k# e% G8 J3 n% j3 T2 M

9 [4 c! u/ O" ^+ Z7 O: D( s4 T+ k匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。3 D+ a$ @; j9 {8 `- w, d

! l1 ~6 \2 X5 S0 Y0 c1 t3 k举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
1 a, h( I; `. w, ?$ A8 }3 P) J
8 ?' a2 T" k' S4 g% Bprint(re.search('^From', 'From Here to Eternity'))  
. H9 h7 L; c' Aprint(re.search('^From', 'Reciting From Memory'))
) L5 E4 t* v5 q18 R+ L0 }1 D$ g( E4 Q- z
24 ^" W8 X/ G+ H/ k6 x
结果如图:8 B; L/ Q/ U2 R8 H7 N5 s  ~# Y

4 I0 o) q9 s8 U' t
( R0 d$ D2 i3 b9 _, H$
+ T1 M/ o4 {4 q/ |. \$ o0 |! @! r- l: Y% \. V3 S% B
匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
. Y, e4 ?, i: W0 F
$ i2 E# ?! O: hprint(re.search('}$', '{block}'))  
3 p0 I" o/ o6 n/ J( P# m8 e3 h0 t: W- m  S- G, a
print(re.search('}$', '{block} '))9 g, ?3 j6 H8 l( c7 Z
, K( ]) _+ z8 Z& D* x- F# p$ q3 D
print(re.search('}$', '{block}\n'))  7 t$ I8 o" s+ a4 c5 o. @
1
1 @4 V" y" X- G0 y2
2 d* \8 D) t1 ]; R. X) f2 P3
2 E. t, e7 N' ~" c7 W; R# h4  o" c1 F+ A3 W; C( H
5
' t5 u. e6 T% ]8 ]2 c8 E! f结果如图:
/ w" I+ c/ K* d5 ?: ]& |1 h: k) M% y  i5 E4 ~9 l. o

6 P7 K6 {4 l8 b% V- W
- I, M/ Q- d$ W8 V% B5 @同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。- d: ?9 y4 H  k" A7 |+ ?$ G6 F

7 F) F& _4 G* h4 n% D4 S" ]1 e\A
- I9 _& l7 ]  E2 L. Z2 u
8 }) m4 l) m0 P  y  M0 r/ Z只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。" N8 V& d! a% Y) {# ?
  b& Q* h5 Z6 U6 @! @& M
\b8 W4 q5 {" N; U/ r# O' j3 i

; Y# e& E; O' S, L单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
8 M0 O% r! B! e# Z' s2 G7 S$ L
. r' y( f: F3 W& D* P! t2 {6 A零宽断言相关信息请点击零宽断言查看。# {5 V" G- M- S% M1 B

( d- u; b5 r. d8 b4 P下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。& D" _% K! Z+ L$ M" {% [! G

1 V" N; E4 z4 Ap = re.compile(r'\bclass\b')0 K( a; z' _9 @$ q$ u. }* h5 ~0 X
print(p.search('no class at all'))  9 [8 U* g& k$ J2 k. o5 k8 b
' _! C4 J# ?" e( F. v
print(p.search('the declassified algorithm')), h1 J" |! c+ Z! w
- m9 s& ^5 N4 w  K
print(p.search('one subclass is'))
& q* u7 [% L3 `# d! ?3 }+ f7 p: T1
  k" [5 w: ~) f) \5 p( m; e  C2. f1 v$ N5 E) v- q% s& P- l6 B1 H
33 ?& B. c. _# J
4
( W! G+ x! I! W0 ^9 b6 R5
) \1 h: J* i5 ^' V6$ r. W; D: G0 x- k# T& D
结果如图:
  ?& N, K7 v2 {, ^  i) F, T& q$ I& ]# V3 W- b: O& [
在使用这些特殊的序列的时候,有两点是需要注意的:3 Y& I* J  y. H  N

$ R" T3 T) F5 q第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。" Y3 V% K5 I- s6 y) ]- v+ ^+ N+ P4 a
相关原理和解决方法点击详情查看。
$ W( _, N, }0 }) n( m$ r& U; B. {; m( G9 @: O1 _
第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
- m2 o3 x: B/ \' Q* }
) G% K6 ?" R7 y( V\B  E1 z. [6 E0 r( S
, d& W7 N; i5 X
另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
. s3 n- ]: H1 f( s5 |
" P3 ~/ C2 k8 I4 A4 N3. 正则表达式实例
/ H+ |# G+ U( R* y7 H3 \# k6 z6 p  s/ e- v$ H
# {- _: J0 C/ `$ a2 j, b$ y
经典正则表达式实例
0 L- R7 s: ]; S& t- i( ^7 @5 A! w1 _. P5 d8 B5 ^: b
匹配IP地址的正则表达式8 O! f# B/ P* M! n
! [, F2 T- k) ?4 C9 `/ b8 X
IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确6 S% _# K. {, m  H
- X( o' B7 ]6 K3 r) v, U: x( ?; u7 k7 X
精确写法1 A- _" M3 S" K; w# e- u1 B

2 |* y6 C% Q( m$ j0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]4 g; m% c5 z0 H0 p2 u8 v! ]- A
(([1-9]?\d|1\d{2}|2[0--4]\d|25[0--5]).){3}([1--9]?\d|1\d{2}|2[0--4]\d|25[0--5])
! P2 F2 c) Y' x/ W8 b原文链接:https://blog.csdn.net/qq_44867435/article/details/1051041771 v' F+ [+ y/ J

& t: y' E: w, b! L  s- s- J0 I' Z' w+ G1 }





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5