QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3255|回复: 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
    9 n# L' C( h3 T  M
    Python爬虫 正则表达式应用详解- s2 b# P# R0 c* `6 r9 W: E
    . [1 p4 m6 T, j
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
    ) U! N7 E& G' E0 W/ ~: p5 E' `+ A; f8 C/ h1 J
    —— 正则表达式应用详解 ——
    1 m7 O/ Y+ s, {( o# U* N% G! b6 S# k1 x7 q3 y0 i; A
    文章目录3 y0 C: N: o7 N: L3 W
    . }- t8 u. w& ]; _7 a
    Python爬虫(二十一)
    5 R! [* @& C$ d6 _—— 正则表达式应用详解 ——
    6 F, r$ C: P, ]1. 简介" w7 }0 t: |/ i' L! G
    2. 语法+ p  a: ?6 W, T8 k; }) }; z. e
    3. 部分元字符应用详解  o4 @" Q0 Z' H3 S# K! u
    ^7 v9 \) P7 A' p
    $8 U+ C6 N  C8 h
    \A
    $ y+ D) f: \. b5 g\b' B% q. K" x( H; c: S8 q
    \B
    9 n# x" _# y) j) H' Q9 ?1 m3. 正则表达式实例
    1 c+ }# `  x4 s6 G% s# z( y相关文章:0 n3 y* v# H4 p5 F6 A  `3 s* O
    1.Python的Re库应用详解(正则表达式的库)
    + e! D% G8 l: @" j9 |% B4 {3 @9 B2.Python的Re库与正则表达式的细节解析(正则表达式的库); T4 r# x, A, j8 ^: _
    / i" w+ I6 l7 d5 Q
    1. 简介
      ]/ d, d; g% e% g- Z( M: Z# P( c. P) S, Z: U" h
    正则表达式:regular expression,也称regex,简称 RE
    8 F! r  U% G0 d5 Z3 k6 J+ E9 k/ l
    ) s5 @- k9 w4 v9 h* h9 S正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
      d. J5 b+ N/ A! P/ y+ }
    1 I. s) l9 ]% ?. s3 f$ o8 |4 h0 O正则表达式是用来简洁表达一组字符串的表达式5 [  i; f1 Q" W

    4 L; n2 B# @5 b* v' Y通用的字符串表达框架2 I2 ~  C# d% K& e9 F
    ( L- k* H) z2 U* H& a2 w
    简洁表达一组字符串的表达式
    7 {% a6 d8 g( E' L3 d. T" V& [: U9 U- Q7 j, f! f
    针对字符串表达“简洁”和“特征”思想的工具
    $ v% G$ J+ t1 E+ m' a+ k7 W, d" o! w1 z, L' u7 Q# b! d% q7 I  I! U( H1 A
    判断某字符串的特征归属
    ( k) P, j$ |; Y) f
    3 s8 m# H* q7 `4 G正则表达式在文本处理中十分常用4 m# W0 w3 J& y( \$ F  }
    ( |5 G; v! N9 _. s& E) ]
    表达文本类型的特征(病毒、入侵等)1 y  W) X1 Q/ P. E+ m* Y
    - X0 \4 f$ H0 H' t2 q8 ?8 p
    同时查找或替换一组字符串
    * C9 a# f' n. S. `( y% F* A
    - x- E9 E3 M  k& N5 Z$ t匹配字符串的全部或部分$ `) p% j  u8 b, u; A( P* M: I$ _

    $ t7 S: q% Q4 s: N, b# K9 _正则表达式的使用( D# g1 s, u8 o' N& F! y8 Z
    9 V: C- c; J9 K7 }1 c) y* Q% T! F
    编译:将符合正则表达式语法的字符串转换成正则式表达特征
    2 ?9 B; r% s7 `; c) ?- `3 U) a+ W7 T2 Y+ ], t

    * A7 v2 b/ L# {4 J& f2. 语法5 V2 Q5 t- L& T/ \, Q

    1 C5 _8 l! r1 v# V$ g) d正则表达式语法由字符和操作符构成" M: i/ c7 v% R3 s2 f, S

    ! v9 p9 ?' k, w3 n) v有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。/ Z" `% _8 F- m9 t' h: |
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )$ \" c/ ^' v$ }9 e* b2 G& I! x
    正则表达式的常用操作符6 b% F5 y  E) Z
    在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发% K( ?: {$ ^. [0 O7 m3 e
    操作符        说明        实例5 V3 S# m0 ^5 S& z+ f& V
    .        表示任何单个字符(除换行符) 【注1】        - i6 \: j) @( U( E  h  @
    [ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符* Y- u$ b1 N- }. M3 N' A. e
    [^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符
    8 c; K. j" D0 A" Y; X8 f*        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等
    * x$ @6 k4 ?; w* J1 k( R+        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
    0 @& i1 U- f7 Z4 f$ Y' r?        前一个字符0次或1次扩展        abc?表示 ab、abc
    ) T- r# d) E$ [- A  n( r|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def
    ) k) Q' \  {! W, U{m}        扩展前一个字符m次        ab{2}c 表示 abbc5 a5 H1 E  `/ P
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc1 D- q5 J8 l, r$ f7 w, I/ q+ i8 A
    ^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头
    & W8 Y8 T" }) @$ `. Q$        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾# b, x4 X: P4 |; F
    ( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def
      d# Y5 t  a' o5 w0 B\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u. l4 a' W1 K  Q. C
    \d        匹配十进制数字,等价于[0--9]        8 O' {; X, ^; Z9 J0 V" ^" W% A
    \D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]       
    0 w4 ?3 }6 [- W5 \. N8 F( Q\s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]        9 s! w1 [' M" W( P. Z) }. i
    \S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
    $ R8 l$ ], g1 _  r' V0 i( e  i& U8 `\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]        / z- {: i3 W; T6 l: `
    \W        于 \w 相反       
    5 U  Q% Y% Z7 [8 T$ @5 Z\b        匹配单词的开始或结束       
    0 U0 ]; F# {8 Z\B        与 \b 相反        * Q2 R# x' u: z) I* g- ]
    \Z        只匹配字符串的结束位置。        # c- Z6 ?  ^$ i/ J8 P
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。
    & p0 S! O# k8 D3 Y( z7 ^
    & _+ j9 U$ t* y$ d# k【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    ! J9 p0 e5 C( P$ u, M6 T  M5 `& T% i3 F
    【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。# q1 v1 e  S4 f# z4 n

    7 t+ f& J7 B) I( D" A' p' g【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。
    , K9 N+ K7 C+ A' c  B/ V/ v. E2 n" F6 F" @, f. y
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。4 X/ e) K1 U: _; \

    + ^/ C( C  F9 \+ G- w' l* V3. 部分元字符应用详解' I- \  p$ x- ^  I
    / _7 S9 g; \4 R1 H+ e0 I. n
    ^
    4 B* M3 Z# O4 N
    9 _4 n, A1 l9 {匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
    ) a, e# y/ _0 h7 |* ]+ H) ?2 K7 {, k
    4 R6 V+ B: n) ]( v# _4 H3 C举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
    9 x' a  b0 h( D* G% ?) j# O, @- B7 w8 n
    print(re.search('^From', 'From Here to Eternity'))  
    0 H, G' m3 h9 {9 h1 uprint(re.search('^From', 'Reciting From Memory'))( U4 ~' p2 l) Z0 g: L2 h: l/ `
    15 j  {, A# Q- _7 h& H
    26 ]" S6 L3 Z3 \8 k5 S
    结果如图:
    1 O( }$ C0 f( I8 }9 w. d+ w7 x0 [0 s2 ]) z, z2 K- d8 R
    & f' e2 e& J1 U& q/ u  h
    $
    # i1 ~& ~* u1 G* B7 b
      G! w1 \* A7 ~匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    + m9 j/ }3 k! V( u; W3 C% ^- G- q+ |6 n# D- [* y5 _
    print(re.search('}$', '{block}'))  
    - V% \! j* `% z' G9 W5 d7 x
    . I/ L6 L: d2 q4 _. Xprint(re.search('}$', '{block} '))
    & E( [; _" w9 B5 P; f
    # ^; [# n% g$ |9 sprint(re.search('}$', '{block}\n'))  
    7 B4 l$ j; q- r+ o# _1
    $ r& H' d, c& V2 f# O1 B* U, m2; W' }+ v9 T! o+ c* z5 A) C4 s' W
    3
    ( |- h; p4 r. h1 S4% P' l6 n+ x' b3 y& K2 B8 i
    5
    6 `* X/ x% q+ o% B结果如图:" L, ^, G) y  @! ?  i

    1 N* Q2 x7 u8 i0 h3 l& i) u: D* @7 }. l/ c7 m
    4 W* n, ]+ \/ g# P& A/ C, _& e
    同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。9 z, }  w* }* Y0 Y
    + ~8 M* c5 A, |' {( _3 h
    \A8 H5 D% s% F6 I9 f! D$ c3 A+ ?# S

    4 C# }% I" M) h4 ]只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。8 K2 E8 M9 h' s  x: j) O7 V: i
    1 H3 y& V% |9 Q3 ]- R% [- H
    \b) D  I( v) f5 [2 T! n: @0 y
    % l  S' d- l& c" ~0 A9 Y+ k0 P
    单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
    8 d& k2 j3 U; |8 p5 Q
    ; Y5 X' F  K# }' T! L6 l零宽断言相关信息请点击零宽断言查看。  \/ A3 q( X9 E! R
    9 R) N! h2 H' |8 u7 M  @
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。% [( H5 k3 o' Z4 m

    ' d  |" D% C7 ?5 tp = re.compile(r'\bclass\b'): j' g, z$ G6 {6 u5 G, B4 }+ `
    print(p.search('no class at all'))  
    & g2 o1 F+ S5 F  _6 O
    1 b/ h/ T  S% d' ?print(p.search('the declassified algorithm'))
    8 F) y9 x1 x; R6 T0 [4 [" V4 c, u0 g+ n
    # M9 j6 A) r+ E- G- N$ S7 Oprint(p.search('one subclass is'))) z& X! x0 d, H, {
    1
      {% {* T9 r8 ^' Q- k4 u23 C# P6 j9 a9 [6 L
    3
    % V6 C% n' f. V& d- J5 Y4 R2 j7 l4" L1 f% P9 @% p2 N$ X
    5
    ! j, Q1 K4 }2 ?" w6 ?6
    8 [: h( s- F( `$ n, a结果如图:
    # h# b* i( J2 H: P1 r3 ~+ ?4 h
    6 b! u% B' S1 Q- I; V在使用这些特殊的序列的时候,有两点是需要注意的:+ l* i7 T( c0 v2 x7 ]$ R

    6 N& K$ x! n( m2 H; f8 s第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    7 ^' p4 e+ F( ]$ y* g9 Z相关原理和解决方法点击详情查看。% G) U4 P/ h* e! _$ ?+ T# A
    . Z) B' E- G* H' e7 m$ ?- a
    第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    , H# O( J; W" Q! N( m
    / E$ q' x) ~- V% y1 _$ P8 N+ C\B
    $ }' v# v2 @9 s. U' G6 d
    / d& u1 w  u1 M, M& S% h另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。" m0 o0 k+ W+ f; o8 Z1 v# M
    , |3 H; B/ p9 \7 Y  h; {
    3. 正则表达式实例
    9 \( t- v" H6 d. }' w' Q1 K
    ) P9 o& q4 I2 }2 I2 ]+ |5 @6 }& P5 F2 @% K, W
    经典正则表达式实例: |- p1 q3 q" [! c  w
    * r* ]' u" t0 F" W0 k
    匹配IP地址的正则表达式
    , c% M) r/ z- k5 n7 L  T$ A. h& ^$ z* l2 W
    IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确4 L2 F) A4 x  j; v5 {8 Z
    / }5 x* ]' z: }1 o6 h; H
    精确写法
    3 Y8 R( N$ e% w& u; ]* E" }) Z) f! G/ P7 P) u$ [* b- N+ P
    0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]# q1 ?5 K1 m! M1 Y8 Y
    (([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])
    * R2 t  v+ h) g( v8 H( j; r原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177# u1 Z4 R" B. @2 P& R
    1 Y0 ^$ m% @) V4 q& w1 O5 m

    5 O  C  G% h3 q8 I  d
    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-18 12:18 , Processed in 0.304408 second(s), 51 queries .

    回顶部