QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3260|回复: 0
打印 上一主题 下一主题

Python爬虫 正则表达式应用详解

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2020-3-30 11:00 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta

    3 A* S+ A. c2 R/ o% tPython爬虫 正则表达式应用详解4 D. Y( h- h- o5 x; t! V0 Z
      o; d- i$ D2 _
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。- v+ _1 O, ?; _5 C* Y

    ! x$ S3 R, y- |( o4 U—— 正则表达式应用详解 ——
    " N) m/ C/ Z2 _2 i9 z" j. {* b  W4 p4 x2 P
    文章目录7 }3 S: v' S1 Q. W' [1 T

    ' N; ^- y" M7 ~8 V# [) iPython爬虫(二十一)
    ( ?1 O9 A- E& E0 f1 |—— 正则表达式应用详解 ——* ~+ D! N1 I; |( q  \
    1. 简介4 I& m- ~) w4 j; s' [( h1 U
    2. 语法
    4 ]1 V! M1 b. n$ L! L( b% R3. 部分元字符应用详解, q) g" T& W8 [$ v
    ^
    # J/ {& m/ F4 [9 ]5 d- V, a$0 x* p1 m2 y) A$ z
    \A
    * x' H# t9 w; G4 k2 k\b5 P/ m5 A3 p- X3 X  t8 E4 }
    \B
    4 E3 Y- ~; K. j" v3. 正则表达式实例0 O. Z& h, E2 W* }5 h+ p
    相关文章:
    2 X# k. W$ Y. P6 A& B6 S! S2 {4 u1.Python的Re库应用详解(正则表达式的库)7 w3 d1 B+ m! d$ d* y& K1 Q
    2.Python的Re库与正则表达式的细节解析(正则表达式的库)
    * T' L% K9 y) |5 z( h" t
    ' ?4 P: |& Z; S4 o% L1. 简介
    9 J" J2 q, d: }8 ]9 {+ |) `4 @. ^$ E1 }+ Q9 n4 ~% H. p: B$ Z2 L6 U
    正则表达式:regular expression,也称regex,简称 RE. v4 R% r- @+ z6 ~4 d; f! U7 n
    , ^" }  m8 [3 y$ ]  ~. t$ A
    正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
    : d) u: _; v9 x8 ^7 d4 P6 {* e+ O. Y1 h  L" V+ m* P. @& B
    正则表达式是用来简洁表达一组字符串的表达式
    9 Q4 s# B6 e! x, K% B1 z5 V9 Q: r8 K1 {1 M! J
    通用的字符串表达框架
    9 t6 Y0 c8 H$ G7 l9 e4 n$ @- m; t$ j/ E4 z$ k- }
    简洁表达一组字符串的表达式4 I" J! ?4 ?; e1 ~' y

    4 T# d: W2 o7 n- n. p" Z) n6 L针对字符串表达“简洁”和“特征”思想的工具
    , A6 r) S% J# B' o' }4 R6 A# W4 u+ a  V' q' Y$ [  _) P8 \+ f4 f
    判断某字符串的特征归属7 A! a. M: Y+ i9 U+ T8 \& A* u
    6 ^) a- G( \' J/ W0 S
    正则表达式在文本处理中十分常用( q2 M) z: ~. x) J$ {
    : t( c- g9 K) d- g7 b* H
    表达文本类型的特征(病毒、入侵等)+ }! H" J2 {- ]* `5 Z* z
    , p' L- B8 q4 D- l
    同时查找或替换一组字符串
    & }- G7 Z3 q4 N& i+ z0 V$ G$ R( r" {. n1 c/ b$ `) X
    匹配字符串的全部或部分
    6 ^( H( J6 b9 d; N
    ; h/ s% w' G2 O  ?$ B正则表达式的使用
    6 [$ s, s& }7 r  N( p  @# B$ b8 G$ r7 Z6 o
    编译:将符合正则表达式语法的字符串转换成正则式表达特征
    0 H. T) I4 P- Q! t# i
    2 B/ x! t, b1 s4 L6 t
    " O9 `4 f- t5 p  H2. 语法
    2 ?# k" I9 V2 L
    4 y+ y5 J$ u+ ~- r: R( Q/ G5 T正则表达式语法由字符和操作符构成" }4 h8 m; I" @6 g( G% k6 Q
    ( [) V6 `" I6 i' k
    有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。
    9 I3 J! k: i) S0 A8 ^! R' }元字符包括:. ^ $ * + ? { } [ ] \ | ( )
    6 r) q2 ]" S6 ~9 s; @正则表达式的常用操作符, C& y5 d% N' F1 _7 z. Y6 D  `4 g
    在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发& d8 ^- {) ~- z! r& D0 o. m
    操作符        说明        实例
    4 _; v) |& z* g/ h: J4 @- R.        表示任何单个字符(除换行符) 【注1】       
    # s, a* n8 d8 L0 v[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符, s& G" ?0 \* N
    [^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符  ~& V8 g# ~: \
    *        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等
    $ i) Y4 X$ ~' n& Q& M# T) n+        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等9 a- d+ j/ o6 b  _7 |: b
    ?        前一个字符0次或1次扩展        abc?表示 ab、abc9 q, g* m; ]# ?0 j! \& t2 h# I
    |        左右表达式任意一个 【注3】        |abc|def 表示 abc、def
    ' r( P+ @" Q4 c( ?! Y3 v{m}        扩展前一个字符m次        ab{2}c 表示 abbc3 B4 `8 T- J* i- l. r, b6 n
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc
    + `" w  a: ^& v3 w^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头1 `- ~% p/ e+ ^9 d7 w2 L
    $        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾
    ; K& U1 J( p, R0 G% z. k( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def
    ) Y% w8 {% ]% ^7 s\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u
    ) A0 J9 b: R- c1 j# n6 K7 i\d        匹配十进制数字,等价于[0--9]       
    / H& _- }4 `6 z6 F; N+ y1 B\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]        , C. w0 b; n3 G4 Z$ a# _5 D8 P3 T
    \s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
    , A6 Y) o- x4 A4 ]4 a/ A- m8 W! F\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]        4 O5 S/ H1 W" i( M5 P6 G
    \w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]        * p0 d' z# J5 a( l; i  {9 K5 _
    \W        于 \w 相反       
    ! D, ?! A% ^+ b' C\b        匹配单词的开始或结束        ( T; h" O' _( ^& p" H3 `2 C- t! g3 ~
    \B        与 \b 相反       
    0 Z7 h: i( ~7 ]6 z4 D\Z        只匹配字符串的结束位置。        + J- y2 p6 M) p1 A# F1 {
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。" U+ E. x  s/ F1 I0 J& ]+ ?1 ^
    0 `* R* }( {5 w3 u: x% B
    【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    2 U$ t  {8 Y) F! U8 i+ h. h8 t$ U1 V. J; z
    【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。9 ]! L3 {% ?% g% M" j

    1 d9 S" V2 J# z- A【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。$ M( x( S3 v6 f: _; w4 |
    $ K2 Z. |2 k' \* }; m, K2 f
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。0 F  A+ K" E# n5 P1 j
    8 X) q" h" w8 H: E. {" l/ H6 s+ Z
    3. 部分元字符应用详解
    0 Q) |! O, h% x8 C
    ' I6 o# `* T" r^" p4 V* u" _/ [- ^9 u: g6 C

    , N- q! ~! G$ Z1 e匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。6 c9 r1 X2 [! V& Y

    - K' I8 O. {& q2 C举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
    3 ?/ z9 F6 u3 D! |; W/ s* G& K& T$ U
    - K7 j* X2 S$ M8 G( nprint(re.search('^From', 'From Here to Eternity'))  9 d4 f" W4 m- D8 }8 S/ Y& E1 a: \
    print(re.search('^From', 'Reciting From Memory')). P! L' r/ a+ n6 O% W- g3 f
    14 ^: k+ N2 R" a) L8 L8 j
    2
    ( B+ b3 y# K9 o- ?/ ^0 Z6 k2 s8 _结果如图:
    % ]) U' {9 b3 s
    & [2 Q# n8 I' ]( `: }; J, u) E
    % }7 A( J- v. K" P1 W3 P( |$$ J, ?$ g. b0 a$ b4 S9 g* g
    5 @8 D: e( h4 ~( q0 H
    匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。( D4 G' L' b1 J! @2 t9 a, L7 q
    % A- E* V5 V0 z, _
    print(re.search('}$', '{block}'))  
    ) T6 [" j9 Y5 o- a3 C4 W6 y8 u
    print(re.search('}$', '{block} '))1 F9 o8 x) K) V4 `. c' U; R
    . h2 l* |9 g4 v2 T, u) [
    print(re.search('}$', '{block}\n'))  
    ) ]  T- |5 D1 F8 a15 B" x& \  v4 o1 k. n+ a3 R) t
    2
    " k: d* S" `  q1 N3
    ; y3 w9 i, |+ q3 `" \4, g" T; T8 ]- J5 H" F9 l+ U# _
    57 Q* F: y+ B' p6 x& H
    结果如图:( }7 p. D5 B3 H0 q: B

    3 {+ D( f/ x1 n+ W  L1 D$ \/ ^* j

    ; J& C( @  y; b( V: m4 O同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。$ Z. G2 I3 Q- `; b* R, N( h

    & b( V. L- K9 U1 [" ]\A9 c. k3 w0 S+ U1 A

    - @  K$ B0 O5 b; b2 D1 y1 h只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。' K" x5 g* V2 d" \1 `
    5 G& z  ?9 y5 Q6 x& m3 b1 X! g  M8 E
    \b
    2 j) P6 r2 [) G% c! G! p
    8 v* k8 }0 H3 p' b- j3 q' h单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。+ Z+ n3 `1 W6 ~/ o' F

    0 ]- [& w  A3 T& P& Y零宽断言相关信息请点击零宽断言查看。
    5 M% i  {. p! |. ]6 T$ y
    . `1 Q. r0 Z& z下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    ' g- R3 a% K3 J! m) \
    - W- m( \1 n9 s3 j6 up = re.compile(r'\bclass\b')
    # x. L2 j" w- ?; lprint(p.search('no class at all'))  % ?0 K, y/ q2 I3 A7 M1 o! D
    $ S' A5 k7 C2 D
    print(p.search('the declassified algorithm')), f0 ~" M# M% w! d4 F$ t

    8 ]7 l6 P- t9 z3 W7 y! k. c2 lprint(p.search('one subclass is'))
    " E( ?+ e% N" U% ~/ w! Y16 `2 ~4 y! e- G/ W0 n
    2* O  j3 ^2 M0 n; z1 |  D
    30 m8 U" J5 d+ O. H% g
    4$ l+ ^. G' g4 ~' H9 U7 O* q. O
    5
    1 }7 q, p% W8 o3 K. e( z6
    ' ^+ L* ?) B5 p6 O$ |  E) Z结果如图:& M& [' f6 X* t, y
    . s" i0 f5 Q: R6 l, h
    在使用这些特殊的序列的时候,有两点是需要注意的:' P8 X/ o2 O( `
    1 V2 x0 D! l: c, e6 X. @  E
    第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。3 Q$ N5 G7 c; Z7 A  s  }
    相关原理和解决方法点击详情查看。( ?! n' b; }* F3 {4 v+ V, i

    & ~- _$ d. {4 a9 ^- E5 _第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    " r: D: P1 h& X
    % A/ ]# Q  o9 \\B/ V) T: P- m* i0 C: d& b7 N* ?: x

    7 e: ~, r$ j0 t另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
    0 J* ]" s5 a& U2 K( y2 `- h" P6 B5 h- l3 Q: j/ H0 g
    3. 正则表达式实例
    4 ~6 r; @  E! N" e1 _" Y: n/ S0 `
    4 M, q$ C8 C  L) h5 R8 Q
    经典正则表达式实例
    * g6 M3 Y' _9 ^, w. V9 b, w2 Q) d4 L* r& w
    匹配IP地址的正则表达式! v, b: o# }& O

    ' G; n7 J& C& H- w( s7 N' i. t+ U7 Z5 J% }IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确
    3 W# V/ l1 t7 U6 D$ @6 o2 M4 T* Y- w% b0 M
    精确写法
    9 @+ O  M2 U6 [1 ?
    - h9 w; i7 Z" t1 v; j( W! ~0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]
    : y- X" r" {! c# _6 A, {2 E(([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])
    * E$ V( Y! l3 }原文链接:https://blog.csdn.net/qq_44867435/article/details/1051041774 t7 t; D& B% D
    ) R% e$ z( O7 I# O& `9 u1 p! c
    , L. g7 |0 o) w
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-4-20 11:37 , Processed in 0.498615 second(s), 50 queries .

    回顶部