QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3298|回复: 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

    & B, \: n1 o9 H. XPython爬虫 正则表达式应用详解/ y" y. M# S9 d8 P0 t5 R$ O# A
    + X  }( x& Z  {; M6 Q
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。# [9 X/ B+ j% v) b5 M
    " u5 g9 F" l0 H6 l5 G7 H( b
    —— 正则表达式应用详解 ——
    ( F; H0 G8 ?/ f0 A: L3 H! h5 }3 m  p+ C" L& j
    文章目录" z/ n- B3 C/ [' p  f

    # P# d' X& ~2 e3 e* mPython爬虫(二十一)" G+ o+ \' K4 c* ^
    —— 正则表达式应用详解 ——
    3 n6 H- a5 \' H7 t" j5 `1. 简介
    ! I" y# Y! q+ X( e( v2. 语法
    ' D! U' L  U1 f( @( a" q' r3. 部分元字符应用详解: g0 T) z/ B, T- q8 X3 M, }
    ^
    : I, A) U, a5 o: i3 q; H$
    8 w2 R& L8 u$ j; M  O- E: t\A
    " Y5 v% r- j6 `8 d\b
    4 U4 o5 K4 b1 B3 U: D\B4 |; j* |7 g8 m8 ]8 V6 r
    3. 正则表达式实例
    1 _. N- I: `, A! b3 o' J/ ]+ Y" z& J相关文章:
    ) U! v$ `; L, y3 N! T. _1.Python的Re库应用详解(正则表达式的库)
    % @8 G+ F% d% B# B2.Python的Re库与正则表达式的细节解析(正则表达式的库). I% S0 [1 ]3 E

    7 o  D: L7 \# l4 @, O% N1. 简介
    ) i: ]# c+ p% ]7 c: t7 R; g6 |" A' e
    正则表达式:regular expression,也称regex,简称 RE
      z% ?+ c& L* w
    * A; P$ G: f0 S! I! o正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
    ; @, ?0 ^' \+ Z3 P8 ]/ j/ V1 n0 v1 S" @5 F5 m
    正则表达式是用来简洁表达一组字符串的表达式9 L. W' g0 w& |/ ^/ K& W5 ~
    - |2 w; s4 s9 Y( w# N
    通用的字符串表达框架  ~6 X0 r. h& w; K5 _, s0 [4 _
    ) E2 P9 K1 Y8 v0 b
    简洁表达一组字符串的表达式
    ( b& Y$ F! d- q/ O1 r% y+ J8 }7 E  z: k, t4 A
    针对字符串表达“简洁”和“特征”思想的工具$ t  i0 O! m( f% t1 D! u5 o) d

    ! V* T7 N4 a: h  {/ E判断某字符串的特征归属
    0 g7 M- y  k8 q2 a! a6 p" a* J3 N2 X8 N& P
    正则表达式在文本处理中十分常用7 y6 O) a8 \! U8 X5 K% }, G

      [; s" }1 W6 p+ r- I$ w7 t' A$ c表达文本类型的特征(病毒、入侵等)( x( L  o: J7 z; \! M! t
      H, y9 W' B, k8 ?$ R. B. g: n
    同时查找或替换一组字符串% |! {& q8 V0 F$ l/ Y. }

    & |3 d/ }( n+ O2 ^/ d0 e匹配字符串的全部或部分
    0 h6 p" e# f4 Z, s5 d1 k! P, {6 l2 D
    正则表达式的使用
    9 a/ E; O" J* S3 L1 v% v. Z
    0 ?  k( b5 K. S- x' i编译:将符合正则表达式语法的字符串转换成正则式表达特征
    ; ]8 t, S) J1 r) n& o2 N* R  s
    " o# r# b: Y& P) o& v; n( c+ Y1 Q0 H+ C' H; X; k/ _8 |
    2. 语法& h2 {) Z$ ~, X6 s% }+ B( I
    ( M1 U- m* A6 }5 w4 M
    正则表达式语法由字符和操作符构成0 [7 v! o& s  h) A

    ' Y7 M5 V) A( c7 u' J有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。
    & C& L3 c1 f8 w0 j& D7 e7 v  C元字符包括:. ^ $ * + ? { } [ ] \ | ( ): j( i8 L6 @9 o% E
    正则表达式的常用操作符7 m$ d) I/ m+ j* y4 u- B& o: ~' _
    在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
    ! k" @7 |+ |. D/ a$ O8 T操作符        说明        实例
    9 ], Q5 z3 J, ?1 v9 W+ u( i.        表示任何单个字符(除换行符) 【注1】          u' |$ d! F2 _7 E$ c6 Y3 D
    [ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    , s! |( i9 g3 Q) g" E. x[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符& @5 n+ D" ?6 h/ X
    *        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等' v5 `/ @! |9 d* P1 ]5 Q
    +        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等2 U" P! Q+ }7 V2 _
    ?        前一个字符0次或1次扩展        abc?表示 ab、abc
    ; k: L! b8 M2 h! l|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def/ g$ A. n0 R8 r6 J0 g: e. F. k
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc
    4 S9 u; |* H7 A7 b3 m1 x{m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc
    ; }. O! f5 r. W2 w4 ~* p$ j. z^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头3 s& a# }& D) i8 T
    $        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾
    9 A8 }  l4 j/ O) i( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def, }' ~; Z' K9 v0 P/ L
    \        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u/ b7 _# {0 W9 g4 v3 \
    \d        匹配十进制数字,等价于[0--9]        : k; _0 k+ {; `/ O; d1 R3 ~6 ~
    \D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]       
    : w; i  h- h7 T0 }. v\s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
    - i. l$ M9 ]; f' ^+ O\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
    " N# P) q3 O8 }$ G\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]        ( w( y) q% y2 Q6 I/ {* C
    \W        于 \w 相反       
    " D& @* j- x. ^2 @+ @, Q/ o# \- _\b        匹配单词的开始或结束        # m9 e8 g* z: k6 ^
    \B        与 \b 相反        2 S- l8 H, R8 R" R1 k0 D0 S
    \Z        只匹配字符串的结束位置。        ; ]6 o4 r& v( r
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。3 q; C9 n& P) l& d
    $ a, B# {; U" R6 T3 D' ?( y
    【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    9 a0 L' f2 }5 T; E: b* r3 T8 S; F+ t/ h( j* K0 K8 O
    【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
    0 w5 g  u# W! R6 w, Y1 I, `; v
    2 Q. L" }9 z" ^% o, \【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。
    3 w! [$ g* A  x& {# s' m. w# J9 ]( ^8 V
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。
    ! K+ w* E; H( x* b% U( \
    6 O& f* L6 ]! y( j4 |3. 部分元字符应用详解
    ) r, S# [8 Z- n/ ]4 f* n  w: ?) M% I
    3 v. B; J, H$ ?" `, H' y^
    : y+ k3 V. f' f3 z4 C
    9 ~3 v8 C. s5 n+ n% p) W6 p匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
    * i8 T5 Q( i! u- E! P
    - W- f& j( R! H4 h: L" h5 r7 l' M举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
    ; t3 {! n3 x: v  G2 w" H6 ^1 @9 y. R, O& B+ ]- L% B
    print(re.search('^From', 'From Here to Eternity'))  
    : \7 e+ c9 w7 P+ uprint(re.search('^From', 'Reciting From Memory'))
    7 d- U2 R  Q, N$ \6 n0 z1' {: u" B2 @2 _* B0 n
    2
    ' S$ x, y0 ]: O7 p2 B0 y- M结果如图:/ k7 }( Q5 V7 v  n* @: R

    ! `. Z* q" T" N" q7 y( P
    9 c% {/ \0 U1 a: q0 A" A$
    3 K" c% ~5 k6 A& }( |: X' }7 Y( \# ?0 y& G* D6 p
    匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。% V% x. D  B, h" n

    8 u( y0 `* U, K) A( ^% Wprint(re.search('}$', '{block}'))  ( O# }/ f0 S- T; b' J) o
    7 b  i# G% }& {. J# o7 I; H" @
    print(re.search('}$', '{block} '))
    # x! S* y/ F+ m& w
    ; q& b# N* _: v! Fprint(re.search('}$', '{block}\n'))  
    $ s: k" Z$ J1 K1
    2 k7 }& L0 q- ?0 t- y- X0 I/ D9 @2
    , Q- e; q4 ^' _8 ^  u. Y3
    2 ]8 A+ @$ F4 y7 [4$ w, N" }3 c* `. Z2 v5 X. k) l
    53 [7 e" g0 ?9 o( |  a
    结果如图:3 m, u( A. D5 I. y4 q# _4 I
    0 P7 C7 h4 c4 e; w- B# U

      @6 i' d9 h0 ~% h* K/ K- c
    - C* v( i: \+ t同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。, M' _. M' O: r8 w

    ! n4 @/ Q; h5 W, _6 ?\A9 L: V! p! S& l3 O8 J: t4 R+ D# t

    . B( @3 Y; L! H9 k) I9 O只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。5 e# B. U2 A6 K6 `

    3 v$ B5 u# E# L\b) J9 }$ {/ F% T

    ! s+ X4 L9 B3 h3 }  V8 u0 S' L: K单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
    9 {2 V* \9 ~0 e1 @8 g: h$ R6 L7 M: [% z* h. u
    零宽断言相关信息请点击零宽断言查看。$ I* T% z" G5 _- K- o& L2 y
    / p- ?0 K, v+ V9 W) n8 ?4 j
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    * B# n3 F- G3 j& i: n7 q6 V& W1 t5 d
    p = re.compile(r'\bclass\b')8 E+ V9 j6 F7 @0 U8 W
    print(p.search('no class at all'))  
    4 u. v" r& {4 i: A% E) u
    $ x: P" V, y; c8 mprint(p.search('the declassified algorithm'))6 Y0 J- H" ~  H) |# g
    9 U1 X9 ^) T; z
    print(p.search('one subclass is'))% }4 g, K2 f+ v! E3 W/ z
    13 s( j; l, u( N2 U: u' [2 z
    2
    & d' z0 ?0 B$ S& q+ D6 Z38 S5 T8 p+ _- \2 O* t, ]
    4
    ' W. H& m: D% {, s7 S7 _5 e# G5) W* P" I& e& h& C
    68 L% W) `: [2 v) H" S! X- i
    结果如图:
      [9 N& s- r: ~9 Y' j2 `$ n  {7 i
    " n- K9 |1 R$ u6 j7 `& E9 y) s在使用这些特殊的序列的时候,有两点是需要注意的:6 Y( k2 X; `0 o3 R5 a

    ; G* H5 K% e& G+ c4 H第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。. E0 P$ _+ f. ~, s; w' W3 ^6 T
    相关原理和解决方法点击详情查看。# W& M( Y9 W3 K4 b$ e" l

    . [; h5 M: L- e第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。1 S& z3 m: m6 u4 j: Z* O
    ( x; C& n% n  @0 A6 I) [' H
    \B
    , T% C4 u  {+ m. s8 o; V9 C7 x1 L. H  ?
    另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。- Y* ?8 H( B  ]3 R
    5 O& T  W" x8 i2 D1 c
    3. 正则表达式实例" f6 }5 H; M: h! ]
    5 g% ^/ l8 M9 s! V
    ; U& Z7 b$ p) o+ C4 p3 H7 k
    经典正则表达式实例
    + ~( |( ^, _( q* D, A' E5 O* }5 `0 X& \# k
    匹配IP地址的正则表达式
    ) m, G. F7 ~. `# d
    ( `% F. `& p6 Y6 q) w! O/ \% P  }IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确
    8 i6 H8 Z! v; }# S% v* A' O0 F7 \6 F1 i! G$ k
    精确写法6 s" p; O6 Z$ V; d4 F6 A

    : q" G! g- b: O& E! b' `7 a" Z( V0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]: S; u  E2 [, ~
    (([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])$ ?* f4 F% X" i, T
    原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177
    8 D3 R3 i7 p2 q- Q4 H. A
    ( P1 a! d; i% t! w% E
    , \# @$ b- p, v5 k5 _* g$ u& r
    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-7-19 15:45 , Processed in 2.260113 second(s), 51 queries .

    回顶部