数学建模社区-数学中国

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

作者: 杨利霞    时间: 2020-3-30 11:00
标题: Python爬虫 正则表达式应用详解
6 X" y  G; V0 m
Python爬虫 正则表达式应用详解+ A; j- @% H/ Q( F

. G. D4 d5 K7 x: ^4 ]7 t学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。2 d2 c* _: ]5 n+ h* ~( [

  k- B6 n) J) W' }- J  @9 F—— 正则表达式应用详解 ——* `; \. Q0 o# z$ l0 p7 d# t7 X
1 e% @# P7 ]* \3 ]/ X
文章目录
6 B' O, U, T* J. p: g5 i8 {
5 X, o# H  F9 }0 kPython爬虫(二十一)  E- M" J* o. F9 z
—— 正则表达式应用详解 ——
* \  W- r% [- L4 j: [: d1. 简介
% j3 s8 C9 l, h! q2. 语法' `& B$ |% C* B  s
3. 部分元字符应用详解* A5 i0 Q* Q' G. s4 U# I  T
^) u6 h5 v" l0 I7 V& N  g
$
' U& O' U" D9 [( r( |\A
8 _, G$ o# p1 S  Z) m7 ~: c\b
- p2 H8 V8 i4 s# i( }+ f8 E  F\B
) S* Y. v- D: R  t& p3. 正则表达式实例0 x; t2 I( b, v9 s6 f* v+ ^3 J& J) S
相关文章:
5 g" ~7 P: \- Q+ [4 t/ T& g  t1.Python的Re库应用详解(正则表达式的库)( k1 x8 q9 G) v0 U7 \6 B
2.Python的Re库与正则表达式的细节解析(正则表达式的库)/ Q, X! i$ h8 ]3 ^2 q2 n9 p( I9 u

' t+ @8 }9 G( r2 L1. 简介2 N. v# a4 ]! Z4 ~
/ }# U+ d" P; ?+ ]
正则表达式:regular expression,也称regex,简称 RE" k5 y  X+ S. |5 u( ?( r+ O

+ g; j. X6 x! M% a! Q% ^正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
6 ?0 P9 h* ~$ x; P4 C) ?: q
' D) H% d* u% Z3 ^: e正则表达式是用来简洁表达一组字符串的表达式
" X. A) \# W9 J
. p5 |3 A- M; T/ Q6 u4 g通用的字符串表达框架
; A. s3 w" n5 q: `1 C- W  [9 ]! E  k5 b! J6 Q7 h7 P, N8 e) v9 J
简洁表达一组字符串的表达式6 Q# F9 {+ z7 H3 M

5 q1 y1 c4 B6 s* v6 B( y9 N针对字符串表达“简洁”和“特征”思想的工具
- B5 c7 \% i8 r' s8 a
+ j6 r  w/ ?6 ?7 w: H判断某字符串的特征归属/ H% j3 E( {( [3 k$ `6 P

: n/ h0 Q( j/ h' L5 ?, i4 x6 j3 |正则表达式在文本处理中十分常用  r( U) \$ B: x) {# n

8 ?- B- i/ a# [% m表达文本类型的特征(病毒、入侵等)2 O  n3 w4 N) w0 h: Q: o, y
, ^; B$ E: W. X( H
同时查找或替换一组字符串
0 d& I$ J/ l0 a0 M4 [3 f. P
. }" \6 L# a& B( j匹配字符串的全部或部分
" p* b4 A" P" A, g: c6 g, i: O9 x, Y9 k# k# x5 g$ k3 _4 Z. H
正则表达式的使用
0 |4 @" A1 T. z+ N3 a4 l! C- t, u1 l( r6 D% T" r/ n
编译:将符合正则表达式语法的字符串转换成正则式表达特征9 H. W- R( ]5 M& G) U' ]

$ Z9 }/ @: Y# a9 z- a+ P4 O
* X# u8 v2 `. q7 t' P. h- {9 _2. 语法
  n, d( b; o: ?* ~3 o& w4 z
' {$ k/ {) {3 r  V正则表达式语法由字符和操作符构成3 u) @& Q( S/ g/ ^1 C. n, B
2 I, h2 D) p/ b! @
有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。
4 G& F" z# V! J, v, S+ a4 C5 K7 S元字符包括:. ^ $ * + ? { } [ ] \ | ( )
( T6 z/ E- Z+ c# a正则表达式的常用操作符' w7 Z9 ^: D6 r, @
在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
9 R8 l1 c1 T& g8 }1 B+ W8 y操作符        说明        实例
0 g  l! X8 h" `$ ^/ z.        表示任何单个字符(除换行符) 【注1】        % j! K1 U+ U) k* }
[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符  W" {8 b# F6 `! S' H% V
[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符
# }, l- d/ T; l# j, f3 Q; t, z*        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等. d1 T; j1 M# ?4 _. `
+        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
* K1 M: h) j$ ?" e& }+ c1 J?        前一个字符0次或1次扩展        abc?表示 ab、abc4 W) `/ `) b0 X  {0 R
|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def
3 h4 n& K5 o7 ^  ?5 k3 c{m}        扩展前一个字符m次        ab{2}c 表示 abbc
7 |1 I0 K/ J) M  s+ p( N1 c{m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc% B* T2 B% `" }; ]# H" L
^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头
7 }6 M5 r1 q' E6 K; h* d8 m$        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾9 P3 e# ]9 w1 Y
( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def; S8 }) d# W, I. J
\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u
( G- z7 D6 f* d2 A\d        匹配十进制数字,等价于[0--9]       
1 k- f+ ?; `7 @& d& b$ L. \1 n( o\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]       
; x" b' `/ j2 n4 u" b' @' c7 K\s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]        ' S6 A+ x# g7 i/ M
\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
4 P0 I0 r4 q( k4 v\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
( J; }0 v$ J; l( n9 D3 f# ^+ l\W        于 \w 相反        , a4 V$ d* g* x: j
\b        匹配单词的开始或结束        5 X) ?  Z- a1 A( B
\B        与 \b 相反        " p" v3 J, E6 A1 l( U6 t% W# q: k& M
\Z        只匹配字符串的结束位置。        0 W( Q5 g5 O: _. X$ j
【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。
$ W" S; f* L, f( W) H* X- |5 S& C. U. R5 q/ l
【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;/ ?0 O, r+ d1 ?! l# S) [# _( X* J

# }. I1 R0 ~! B% B. S0 n【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
/ L" b- U" B5 A! m5 L9 G' _3 D* ~: p7 q) {/ {6 g
【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。
( k8 ~) e1 Q  E$ @2 f1 u# y, ^. Z2 P1 m6 n; `
【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。" u7 @& d* k+ |2 }

5 Z" ^6 M" ~8 L% Y4 ], U0 n* h3 P, \3. 部分元字符应用详解7 ?; j( Q% t. y/ ^1 `3 l' V$ c3 x

6 G2 ]) N0 u2 @5 w+ L7 `0 \* H^) Y) ~7 G0 K" }" v( I
$ b/ S# v! k: [, p
匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
* ^+ Z9 k% {3 |& V- Z
  v9 M* E, A0 g, W. o9 K: B举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
- z+ n5 I$ @4 m$ l( I
& x, e* H# A, A  ^, Tprint(re.search('^From', 'From Here to Eternity'))  + I/ C3 ?. h0 J& K! J. `2 y2 P
print(re.search('^From', 'Reciting From Memory'))" g0 X$ {3 B6 T: Z! C% ~' J
1
+ T" @$ }8 k. A+ c" Y6 ]* C9 ?$ H2  _$ [" l1 m- _5 \# q
结果如图:; c% e7 j2 o, Y
9 ?7 ~% g5 B( o9 D; k

' Q3 z; {) O4 v) U: N) L$
, V, N( N5 B0 l: E% ]* U1 A$ [
0 G+ e' C5 x" `& _7 j( N' x/ N匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
3 ], \( q5 X  j
  {- X& c- D; n% g  H! Lprint(re.search('}$', '{block}'))  
  w, ^: v. C+ \
$ I( A  b! h- u6 U- Vprint(re.search('}$', '{block} '))- @: R. P5 j: d9 n3 a( C, m

- Z( X( i6 t# U9 Mprint(re.search('}$', '{block}\n'))  . u, u- G6 o1 [+ m; r/ \# \
1
) I" n+ ]( o' z: b3 C6 F* V0 l$ N) C26 o, }) b* I6 V( }. `5 z( f
3
- a7 Q4 k1 ^9 |( r6 Q4 Q) H, c# t40 K" a/ X5 d; ?- ~
56 r' _( I9 @% f7 x3 s& c
结果如图:, o) C( p: a9 W2 }# {

& e- J2 \% J# \. j& B' O1 I# ~" l* Z- i3 S" n1 \

# E7 B5 b2 c) t# t4 s* x9 f同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
4 G: x/ I0 Z8 X; i) o4 ~# G9 z9 s( t" D/ g1 `- U
\A" U  d) K) V9 s( p
8 ]2 o8 [' I* X% d
只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。
2 ~( y- g6 R/ E6 y! O: `$ `
! X# M; j; [4 r( |3 f! A\b
! R: ^$ c5 _+ _0 }. T1 K
/ E/ |# q- l. @. l. P/ E" [单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
. ]) P0 l% Q$ a2 C* ~0 u' y$ d! z+ e* w
零宽断言相关信息请点击零宽断言查看。3 r* z! \7 g; H2 L. g
  {* Y, z- _- [& |; Q- h' e2 R! t
下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。0 ?/ k0 \: a- j) B

* U. k/ U/ }4 Ap = re.compile(r'\bclass\b')6 U# g& z! B: i( D# J2 I, o
print(p.search('no class at all'))  . e2 M6 a: ^  c# F& @! N

" t8 o; `8 E$ i, |print(p.search('the declassified algorithm'))! m; _$ N/ m6 f9 Y

- M' y, @) Z( g3 d& s( Fprint(p.search('one subclass is'))& F4 F* |+ E# q6 {) ^& [) u2 m
1
& y' l8 ?2 D8 v6 }" Z; |2
, Y- j4 x4 n. t$ u37 d4 S+ y5 e, u- G$ e
4, B; q) s: k) Y/ W
5
& H* {9 L  U- v; h0 N9 L3 F63 u! ^# x* {) i0 O+ S4 s
结果如图:
/ y+ K9 q+ S# e% d5 K: u
0 f+ [$ O2 t$ q- _在使用这些特殊的序列的时候,有两点是需要注意的:
* W6 r; \- B1 i; a7 Z. s$ D
: D# A8 m) f$ q第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
0 W: k# S5 L4 `9 z- M. A; v4 Y相关原理和解决方法点击详情查看。9 X- g2 G, D% M: m6 b; J
3 Y3 w9 a+ D' F" J( i% ]# F! o
第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
  N" p; Y- }' U1 E' i5 T
2 n$ G* n) {2 r5 \\B& F8 G" U7 H4 e/ {; v+ J9 n2 w: q

; A8 n. |. G8 A  O, k* }另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
; W# n, ]$ \! }* S0 w4 q/ v. @8 N+ i6 u1 g$ C3 V
3. 正则表达式实例
9 p0 y7 H: s4 x  e; y1 I. ?  _+ W
# d  {6 c3 X- J2 y* O% q: n/ c* c( k+ C" N; n6 {. R5 m
经典正则表达式实例% m# q- x  O0 `& y4 J* w
* q' m; ~# w$ k  I1 S
匹配IP地址的正则表达式
6 `0 O& b+ A) h, p& a9 h, ^: r+ ^9 ~7 u. s
IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确7 X$ a, z+ i: y- D# m

7 U0 d3 h7 Y, Q% p5 f# n9 M精确写法
  Q# s1 ~  `! [7 g# M, A9 E& X
" q7 L) V/ y& I$ W( g5 c  r# J0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]5 a- w# N6 z- C2 U- ]
(([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])% @: O9 J' Y5 t; L8 k
原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177
( o, A7 Z8 q7 b7 Q, M, {/ u
% ~3 D2 j: q  Q' g4 Y/ u) q
/ Y+ U+ y% |4 l, D0 S7 i+ Q/ S




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