请选择 进入手机版 | 继续访问电脑版

QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1172|回复: 0

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

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

5250

主题

81

听众

16万

积分

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

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

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

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    发表于 2020-3-30 11:00 |显示全部楼层
    |招呼Ta 关注Ta

    : s# Y: d! s% `2 ]4 p2 GPython爬虫 正则表达式应用详解
    4 s4 y- }4 O. `
    ; c7 @% C2 ?& B学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
    1 _6 [) [" w6 A5 M: L- k8 y
    2 d% |  ^* H! y% m" h—— 正则表达式应用详解 ——
    : ?$ x) y3 a0 Z! I- T/ O7 ^5 q% d( z3 F) O# D
    文章目录* ~5 L; d' s5 u! w

    ' \2 ^) g, U; L& XPython爬虫(二十一)  J" a3 P: p( v  Z+ `9 |9 `
    —— 正则表达式应用详解 ——; M2 u& k( K" x/ m: e# v" P
    1. 简介0 [! _7 A: C' }$ d6 T. E( L
    2. 语法- f! T) C/ l: b& `
    3. 部分元字符应用详解0 X, Z0 G; X  c
    ^
    - o5 A# x! x1 C+ u8 E$5 f# P$ g; j- R3 P: \% a. x6 u, D4 E/ N
    \A
    ! Y! \5 z& I! Z3 ?" f\b  ^, i9 t/ o) w* X6 e2 p
    \B9 H! b; v/ P2 \( k  `4 z$ a
    3. 正则表达式实例
    ) ?2 e* \; N' c) O- ~( l$ t) b相关文章:" d! p$ R5 P7 y: d& L( e' s) M8 J6 x
    1.Python的Re库应用详解(正则表达式的库)7 W* `7 l+ e# z* S1 Z' _
    2.Python的Re库与正则表达式的细节解析(正则表达式的库)# |2 z% s+ f$ r" i. V
    2 j- A! F% ^, m& h
    1. 简介9 R& t. P0 C4 B' {- d

    , d1 c3 o( m: c7 u- b. U正则表达式:regular expression,也称regex,简称 RE
    9 w* @0 {* K1 a6 ~3 G7 v
    1 J5 e3 c* h  w& Y. Z1 \正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
    % \8 \6 o7 w# z2 K& |5 n4 ^; B- C2 `6 e( T' z3 c, v$ |& y7 }9 _
    正则表达式是用来简洁表达一组字符串的表达式
    5 K, @* w* u( ^! c; L% @' a9 E& s$ n4 N. _  B5 N
    通用的字符串表达框架& q, ~8 g6 A* d) H) k
    7 W0 }  |/ L9 U( O% |
    简洁表达一组字符串的表达式
    : _: N2 m, n) e. l. ?; H
    4 W0 L! t' C% m  T针对字符串表达“简洁”和“特征”思想的工具$ V0 g' k, \4 {! E, D

    ) e) `' G. K: {2 N9 }判断某字符串的特征归属" |9 x+ b7 s4 x0 Q. a

    & K/ @/ e4 T$ Y+ ]" {9 G0 I正则表达式在文本处理中十分常用
    ; f8 q3 ^/ b4 I9 d, D0 E* g9 }3 m9 G5 e* x! X
    表达文本类型的特征(病毒、入侵等), t, e5 q; Q! h/ i! N! Q* T; I

    6 A0 q/ V( M+ K7 E; I# q3 [同时查找或替换一组字符串# h; g' }) r  w/ |: V# _
    - V! Y# K8 T2 I" b& a* Q' h
    匹配字符串的全部或部分! H, q1 w$ Z  X' f' i

    # I3 J# x, a0 o/ S% l0 S6 e* d正则表达式的使用
    , f' u6 }- `1 y/ f& _
    ) S5 }, [9 ~. y. |编译:将符合正则表达式语法的字符串转换成正则式表达特征
    ' t* O: G% F" R) k+ p/ B2 d
    & y! p* M1 @( N. E2 q2 }+ l& G% f  c' I: |& [* U  ?
    2. 语法
    " G0 V3 a0 T- p- r) F, d6 s% _# n# H- L* ?# `! j$ T/ V
    正则表达式语法由字符和操作符构成
    % x9 \! [$ U/ p+ k- }' n- [1 t+ N8 Z6 z9 J
    有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。
    - v& r( t8 n; L% Y% F元字符包括:. ^ $ * + ? { } [ ] \ | ( )7 d. ]6 ~2 Z8 U4 Q* @9 J4 p
    正则表达式的常用操作符
    0 b$ |9 x/ }9 Q2 _$ M在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
    ; ?3 j1 m$ \5 S. S  H操作符        说明        实例
    ! [1 j* S  f" u7 X.        表示任何单个字符(除换行符) 【注1】       
    7 ~5 N, j) e- V4 e  {) a' H[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    0 ]1 L, l- F5 M, n3 `: A1 s8 s% V[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符
    ( V/ i4 E, b2 ^*        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等* U6 ]5 N/ Z0 Q8 ?" R1 U  c
    +        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等+ a, w0 w* q0 X6 b0 |, g$ a
    ?        前一个字符0次或1次扩展        abc?表示 ab、abc$ g( e& s1 L* g' T, X" `
    |        左右表达式任意一个 【注3】        |abc|def 表示 abc、def; F" F2 F  y, h& ~7 x
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc/ v, U9 k5 L- ?
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc
    5 O  S# o. P# r. R( W^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头9 T( x. k0 i5 d5 v4 t  j
    $        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾
    3 T% Q/ w! Z& s6 T( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def
    # D! l/ d2 D$ T0 l# }( j  T9 L\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u2 s1 }' f3 u3 _) C
    \d        匹配十进制数字,等价于[0--9]        8 f# I- E) }, `% E  g; E5 S& A/ z
    \D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]          Y: t: y2 I0 \6 w. m3 W
    \s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
    + X* D  a# e" ~\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]        6 C% @& S4 u. m8 O% ~8 m
    \w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
    . k9 ^  P; r: ?/ X3 C; I\W        于 \w 相反        , f( o% o5 c* z; Q
    \b        匹配单词的开始或结束        # m5 l3 G3 i, [- S) R& O) l6 d
    \B        与 \b 相反        & h) j/ @+ D3 r1 F8 U( _7 s5 a/ w1 h
    \Z        只匹配字符串的结束位置。        5 K  g% q- t1 _. z8 [+ M
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。6 L  F+ S5 D  l; {! H
    ( E+ }$ }( [% k2 b3 |' y, N# O
    【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    , m7 A' G! }3 o2 A
    4 ~. N& _9 `2 n! F# U& ?" o【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
    / Z' G7 _& ]: J( ^4 K' X
      `% {$ l$ |4 g' I" }( J【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。% X0 N: H$ t; d( r$ b- p+ j: X! D- d
      l& i" \2 b# D0 M) g3 M, q
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。
      m# l! r6 V+ W; F" v8 A5 }( ]' J. e8 l" O- \2 k
    3. 部分元字符应用详解- p' v' O: J- Q9 X

    ! p  }+ M& s( q; H9 Q" ~^0 {" R0 ]! [' s3 S/ M5 S7 O! [
    * T# e9 |# j( F
    匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
    + d' P* @0 G$ h3 j( I! r* ^# j5 [: h7 ~) [7 A' V
    举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:+ J- W8 N. ]7 u. a
    - h2 a  m# L+ r, {" B
    print(re.search('^From', 'From Here to Eternity'))  " I9 P  X" [! t5 O  M' n7 b
    print(re.search('^From', 'Reciting From Memory'))
    ! o4 D( u  d& _1. G  ^% W3 a' M4 O
    2
    $ t0 j4 t8 p% h. D  S结果如图:
    : \4 F: z2 D& F9 ]  V" K( y
    * R8 I6 a2 u) t" X/ u
    , l( a5 i6 i9 k$2 C$ H; E% X- H$ H  Z' n# s

    / X& |' I; v: i- K! f* A2 G匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。- f6 h. S5 D* G

    ; n; `$ v* U2 Z4 r8 [print(re.search('}$', '{block}'))  ) c" U  r, P8 d4 ~  Y# y: r, |
    ) m) o3 h  j1 c& Q
    print(re.search('}$', '{block} '))
    ( _  v; Q% N* N9 x0 @0 `6 j+ y5 z6 H; Q' k- v( I
    print(re.search('}$', '{block}\n'))  
    , V$ \$ J# `) _) D5 O1
    2 q9 }0 `/ u, F1 V5 {# v5 n3 v, \2
    2 d8 ^: a- A+ E0 R% V" ]  u& N) D37 P/ x; m  F8 R8 g" R
    4
    2 Z, d; ?( r. t1 ^& b8 e51 X- O6 d' `% W" N
    结果如图:. t  T) m; V; I

      r! |3 O6 y# ~8 h2 z7 U& @. Y; k9 `$ ^7 U
    / L# T. u% b  ~" M6 }( C
    同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。2 k3 H; D4 C1 `

    2 H" G: e# S& v! y\A
    7 ^9 k0 P: U& U# [
    # o$ T, y( g" _& q只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。/ ~8 h, v2 k2 h7 N7 |

    1 L7 J; Z5 d: I! K$ S7 C* @\b- R  _& `$ k' G
    $ e8 |" g$ L# @1 F* i: D% V' s
    单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。$ g, V0 m/ Z( E! ^
    3 [3 s8 R( T4 Z3 |1 b0 D# _% s
    零宽断言相关信息请点击零宽断言查看。5 @7 L7 J* t$ M9 N6 R

    0 {) ]. W& i3 _4 n5 m8 o下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    . ]2 r& b. y. s$ b& B
    . K# T- o  Q' C9 p+ p4 q4 q; R/ \/ ]. bp = re.compile(r'\bclass\b')
    $ Y0 I% `9 e! S0 X1 dprint(p.search('no class at all'))  
    ' h. g/ g) ?. l: C, m0 Q9 o& a; |$ p" H" j1 A( ]1 [- G
    print(p.search('the declassified algorithm'))
    * K3 O- p+ t! ^0 w! Q" w- x: R: l8 v7 h# A  M6 l& z# U* b3 k
    print(p.search('one subclass is'))
    ) Z0 R5 [' k+ P7 f12 Z* _; c2 R2 L8 m4 L
    2
    - k0 d9 [& J- s# m; h3
    % |# |( k' d1 ?  n4
    ( C) r2 F1 J- U3 Y) `5
    , _8 u6 l6 H+ Z" P0 Y7 n6( Z8 M9 X" r$ O; W: r  ~$ `
    结果如图:
    ; ^+ |* W8 |* ~  t5 Z
    ( C! x( B6 g, k) t在使用这些特殊的序列的时候,有两点是需要注意的:
      i* {4 |# Y; M  B- c  E. ?- T/ o4 R( h$ J; U6 {  n
    第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。2 N1 \9 }& |; I0 u  h, H2 u
    相关原理和解决方法点击详情查看。, e0 c0 j! o4 D& V8 k3 m, C3 I

    ! p9 q# o* y4 V% b5 n第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    : r% a' e  \. K2 _; I, d- h
    4 M3 C* c% ~. J9 T: Z0 \/ j\B
    / X1 M( |0 p) ~, k
    . g  B& \9 Y1 [- I另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。2 p$ v( j( g. Z0 ?' a
    . b8 Q+ `! U8 L# ~6 g* `
    3. 正则表达式实例
    2 w/ W8 [# {0 k& ]& r
    - I' Y- e9 Q6 l3 v
    # {; Y  o- W4 K9 Y经典正则表达式实例
    - Q+ T5 P6 Q8 R' s& r0 O3 a, A3 K) X  ~
    匹配IP地址的正则表达式
    . d7 M) y) }0 R6 X# H
    , a; @& g$ L: RIP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确
    3 D9 D/ O7 i# r1 e4 h1 K1 w
    ) M) _, s2 |, d! c( Z2 M精确写法
    . ?+ L* |7 G+ e8 g/ g9 r6 ^, K9 `, Z) V: N$ I3 ?  }
    0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]% W+ D3 @4 m6 Y4 J' T
    (([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])
    $ G# y/ d% {6 K; C. n( c原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177! u. f6 B. |9 @

    $ c: W: U% h4 i; F/ L/ O  K
    6 ~1 l! F$ g: z" {: }" c5 f* C  t
    zan
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2024-4-17 06:10 , Processed in 0.376094 second(s), 51 queries .

    回顶部