QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3318|回复: 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
    + x- J, ~  a4 x+ F  j- Z5 z% R
    Python爬虫 正则表达式应用详解
    3 L9 E, }! [1 U- u) L4 y! f- x
    , M+ D$ l/ M% ~  ^学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
    8 u) i- b# ?3 J( |% r* p
    ( G0 X. W; P; _; v6 _/ d& {—— 正则表达式应用详解 ——
    3 {5 o  Y- Q1 p0 G
    9 I% n4 ]3 b7 B文章目录
      S, {" V! S  |1 z% g% C9 k6 S( i5 W4 o1 w" Q1 E' |
    Python爬虫(二十一)' n) ^9 d6 A& w5 o1 H
    —— 正则表达式应用详解 ——8 A0 r9 k" j. t9 L  c! J5 f
    1. 简介
    " G5 d* X# `% a+ L. X0 T: R% v1 C2. 语法
    ! M( I0 s: x0 t7 R- v3. 部分元字符应用详解
    + \9 \. q! J( X8 C: u+ r^7 f/ B2 m! J$ ~& k6 s
    $. b: ^2 B! K4 |9 Z5 Y
    \A
    8 ^# w" y; J6 r9 a\b. c$ k2 W7 j$ \4 S* H
    \B2 \0 P2 A  C: j
    3. 正则表达式实例* u6 Q+ _7 p- G! D$ f& Z
    相关文章:: h% s4 P* j; h' J2 |& F9 e2 r
    1.Python的Re库应用详解(正则表达式的库)
    4 k/ f3 [( g% B- X0 \2.Python的Re库与正则表达式的细节解析(正则表达式的库)5 _% O1 h0 Y$ D9 @) U' Z) _/ `

    0 o' Q  V/ f* v2 X, l1. 简介
    / S( z5 }/ I  I" k& ~. T. q; E% t+ |4 X) }
    正则表达式:regular expression,也称regex,简称 RE2 X: W( D) m$ g4 V# P

    " z) e" \# a! L, L/ I正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
    6 |! t, p% m! h8 s) N" O
    5 E  e8 W" R+ E) r正则表达式是用来简洁表达一组字符串的表达式
    4 x# h: `7 x5 O9 ^  G  V5 S. g# |+ D9 M7 B' c
    通用的字符串表达框架9 [) ~  L1 @4 K, c' L
    , V: K! s$ e* B& ~" B2 q3 j: b
    简洁表达一组字符串的表达式+ h) F% ~  G" j8 h& J) u

    1 ~' J2 x4 T) L, z4 N' m针对字符串表达“简洁”和“特征”思想的工具
      S0 R* b' o* g0 s4 T; Q' Z' {1 d2 T- M, R
    判断某字符串的特征归属  {' Y. j0 C# T3 v' P
    ! C8 L/ I% c8 M/ R, ]
    正则表达式在文本处理中十分常用# a4 x) ?: t- [, @8 N

    ! B/ R; Z6 e! O表达文本类型的特征(病毒、入侵等)
    0 B/ H. s$ P) {( ^/ n" b: s- u" U% E$ C& f& R! }
    同时查找或替换一组字符串
    ' Y+ P  z6 P3 q6 D
    1 I; J- p+ F# p匹配字符串的全部或部分. b, Z* k$ N" b0 `

    ! h& R4 j! t$ A正则表达式的使用+ K- p8 T5 v! E' A! {) ], E. h

    : Z" \. m! |% ]& [编译:将符合正则表达式语法的字符串转换成正则式表达特征
      J/ N8 V, C; \- t8 }+ k9 \$ b0 `4 G2 u7 ?5 D5 X
    % q+ V9 }$ Q, c7 [8 C
    2. 语法- c; K# Q' y) P$ K$ J
      b, K/ g1 ?$ [! k
    正则表达式语法由字符和操作符构成5 O9 N, f& R5 e0 a5 b

    ' g7 E, H8 D& A$ b2 `( O有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。4 L1 ?0 b; B% H  b
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )
    & A4 l- r" C' G* C4 W% R, [正则表达式的常用操作符
    . [* d$ s7 M* |: F) e- U) v在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发, |2 w+ f5 e" g$ _: v' {0 S
    操作符        说明        实例' _1 I; _+ @. J7 e3 y1 L7 u" K
    .        表示任何单个字符(除换行符) 【注1】       
    ) R( l+ @. ~& h" R* \8 z) ^[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    $ z3 P" ]+ X3 C. r: A% m" o[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符+ }5 v/ f# ~  d( E, d% x. F3 _
    *        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等, a! \6 @- ?2 \" @- U- Z
    +        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
    ) @6 P- R3 X$ j4 \; u?        前一个字符0次或1次扩展        abc?表示 ab、abc. d! k- h' X. w* k  A# i3 l! g: ^! z
    |        左右表达式任意一个 【注3】        |abc|def 表示 abc、def, z6 \2 y& O7 O$ b, u
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc. V; B  a4 f  V2 G: k
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc, N+ w6 s. D! z% y6 j7 h
    ^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头+ J8 ~9 Q. [% U6 U
    $        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾
    0 C0 O  I  g7 d1 y) K5 N0 u  V( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def/ q$ r" j/ \, W( C" c
    \        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u- T! j) T, y7 n# M/ @
    \d        匹配十进制数字,等价于[0--9]        7 d& }+ b  J! i) ^# O
    \D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]        ) g$ K* |, d1 v" f. n  i3 S1 ~- O
    \s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]        ( U3 _6 i2 S5 h' H
    \S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
    1 b" P, Q# |% D, U\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
    / `# }/ O& i& I2 N\W        于 \w 相反        2 E9 a. X% I2 K# a, _
    \b        匹配单词的开始或结束        & p1 _7 q4 ^4 Z1 \" R& i
    \B        与 \b 相反       
    9 w0 ^' I7 P4 j/ l% Y\Z        只匹配字符串的结束位置。       
    ) ^/ t) D) C" V* X8 M( y9 M0 Y【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。
    ' d/ y- x  @. i' y2 d$ Z" X8 ]6 @  U& q6 P( a6 b* G9 H% m0 M
    【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;, M* u- T3 g& v8 v( y1 m

    $ w% |9 [: P& U* D【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。9 G, |5 l4 @( _5 u
      R5 r) b% ]* F5 F$ [! ]
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。! K/ d9 I3 m: H1 [7 R
    : h1 D+ x$ S& W+ d5 W
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。
    4 G( s/ }. V$ R2 D. |& i4 o3 E: Z2 K. z4 @* v9 ~) I! N! r  s
    3. 部分元字符应用详解
    % T3 J0 [& L5 I, ~" x5 c* w% M! I# _9 Y
    ^
    * D, C- y2 o  D1 V4 I! E
    $ c8 q* R" A0 B匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
    ' l- }7 H3 [) s. W+ }( r9 L0 A( I+ X) w1 I  I
    举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
    7 p! G- y4 O; P' F! W
      S3 w- k9 r3 N1 j- G6 A1 iprint(re.search('^From', 'From Here to Eternity'))  
    - V  @* r( x" M6 [print(re.search('^From', 'Reciting From Memory'))7 I* P; ^; K- P) q/ M: L) o
    1; L+ V! m) W3 h+ X# ?8 I
    22 ^, `8 E8 ]# b$ r
    结果如图:
    & z# @0 J5 d3 ^) e$ y! U4 s, c0 `# I* O1 D
    , o! z& M$ \, |( f; @: m
    $
    / L4 i' w# T, Q0 P  [( z. G3 A
    5 o# V7 Z- ~1 y9 R  ?4 F1 t9 n) i匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。5 U: j- L! u& U- A6 f9 l; K6 s9 R

    # l+ O: R* ?0 [1 N* o2 C% {print(re.search('}$', '{block}'))  5 N1 l/ r7 \. C  j
    : X! T' C& ]0 r& Q
    print(re.search('}$', '{block} '))0 G+ Z+ g8 E5 O/ ~4 R* x
    $ M8 M9 a! O2 Z7 l; z
    print(re.search('}$', '{block}\n'))  
    * e# y) Q. ?# j, ^6 V1
    : O6 o: L4 I" F8 U28 T& C# N+ F' o0 j  y6 q% j
    36 B2 m5 E( v) E
    4
    ) v' j( [. M+ m$ l5
    8 t1 s/ e; a* p( M' Z结果如图:7 F% k( U9 C3 |' j$ J% J1 y
    ; ~7 J3 j7 s- d& p5 L( }6 N2 l+ s; n6 r

    / _. C; G) ?$ K" N% Y1 Z2 j3 s, U
    # L/ ~3 q4 m4 G+ r4 ^  e4 J同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
    - |4 q5 k! j7 N
    3 d2 T# \4 d0 J0 _9 s0 X% D\A6 Z+ p5 W* q. U1 M" g

    ( K6 z* B- H& v& z只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。
    / A; m9 w  D' t! A
    5 G* T# l; Y. d1 }3 S\b
    ! j: M8 H- m1 x" c# W" D2 z% j9 z  V" P. N
    单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。" E+ j& t: M) `
    * \( b# i: |, H- d/ r
    零宽断言相关信息请点击零宽断言查看。
    8 a0 z# Y+ L8 S3 x2 K2 j/ K# R. w2 Z2 }. ~. E( o4 I
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    8 u4 u5 o% Q) ^
    1 T: F% E0 X: t# qp = re.compile(r'\bclass\b'): \! T: p  E1 F0 i( {$ c2 @) Y
    print(p.search('no class at all'))  + N* r; n( h5 H) o+ T- Z% z2 o! N

    9 G; n: ]* \+ M3 G& xprint(p.search('the declassified algorithm'))1 `4 k3 p* U+ x( z, a# b9 }- w

    / Z$ ?8 L% ~" q! r: Bprint(p.search('one subclass is'))
    % q% d5 l& }! i1
    - u8 h4 S0 W. J5 b2* X8 I6 H( g. r; {+ V4 {# G
    3' X4 I6 Z. E3 V% p
    4
    ! x) D9 |" q2 V8 W50 C5 h" g; b6 d- M7 n& q  E- ]
    6
    0 O. s: m1 {# N' o$ Z结果如图:
    ! C7 k0 F+ o) d) L6 e2 i
    3 c+ Z9 n) d8 t0 [, @  x在使用这些特殊的序列的时候,有两点是需要注意的:
    8 D* [, I' f( a) t  V1 ]2 L# S
    7 u6 `& C3 `' K' G/ Q! ^第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    & w! H8 y* C, F4 m相关原理和解决方法点击详情查看。: j6 u" b' p6 ?% Z
    0 H6 a' ~- \7 R, l4 ~7 t
    第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    ( B% s6 f" G% F* F
    ' s2 R+ {( Z% Q6 ~$ A# y+ C2 T\B5 |0 V  h3 M; T/ T2 l/ Q

    7 Q; ?% x% s" I另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。9 Y9 a5 u# t/ Q7 G/ |' q  _
    : |$ ?/ s3 Z$ z3 n) P- G
    3. 正则表达式实例( d4 e. r% f5 ^

    $ j5 m( v9 W/ u8 g2 X) K4 s! }  o, R4 E$ `2 I5 d
    经典正则表达式实例
    , b: S4 W4 \# q
    1 `* c" R- \: r! x( l匹配IP地址的正则表达式, T6 M! W4 }% h9 Z/ M4 `/ X0 ]. t
    7 ?7 S/ d3 v, ]3 ~7 Q! f1 [( a
    IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确; X, `2 E9 R& A9 \

    ( v( n! C5 j: u4 U8 F1 P精确写法
    9 j* d) {: t3 P2 f0 c" p7 L9 J! J5 h7 z
    0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]
    . ^* q3 \3 _6 U; b8 _, F$ |(([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])3 R, ]' u' O3 N& o; J/ W
    原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177
    " B7 t) Y4 ^" [/ I. u5 y* ^9 Q+ I/ I* N- E+ A8 ~4 H, i. ~
    ! o0 R. E2 ~9 F4 z
    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-9-1 18:25 , Processed in 0.434981 second(s), 50 queries .

    回顶部