QQ登录

只需要一步,快速开始

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

    6 {, R# Y1 u  A& S( n4 w7 a4 ]Python爬虫 正则表达式应用详解
    + a( h9 A' f, p: N, Y( ~2 q7 y6 G8 m: k+ C9 B3 G" r$ w
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。  o. P9 Y0 ~$ r' G

    : y. Q$ C# T0 ]% N! z& @—— 正则表达式应用详解 ——
    - q3 I% L( M" Y
    / R* M0 T; _# g: S& e! \/ W, H! z! a文章目录
    , \3 I0 [1 H5 `  h
    ! }. [! z( g& N% e* kPython爬虫(二十一)
    9 Y$ e: U; y, s—— 正则表达式应用详解 ——
    2 x4 |- u& ?4 W/ a& i7 c1. 简介' N9 c3 e& T: H
    2. 语法( y7 a5 h0 g. k% }
    3. 部分元字符应用详解
    1 {9 j; z. M6 ]1 f" C; P1 l5 A; b^
    : V# y8 z6 Q: E8 H: h+ B$! T3 n  O' @- W, A: I% J$ D! G
    \A
    3 p4 m5 f' U0 \3 _: }\b
    3 Y4 i+ ]! |. L& E" F2 a\B
    # X. x& t9 w8 A8 J, G3. 正则表达式实例
    ' s0 G, {+ f- z6 @, d% r0 e相关文章:1 o! n7 v9 R4 N, l8 z- _
    1.Python的Re库应用详解(正则表达式的库)
    9 c& L+ q. l" [& }) j5 O  i2.Python的Re库与正则表达式的细节解析(正则表达式的库)
    ) h# Y  w* q& W( {
    - p* U; _7 o) `* L# p  {1. 简介
    , {! b( C. O8 D# z+ \# w9 n8 w7 w  i1 @2 s
    正则表达式:regular expression,也称regex,简称 RE5 V8 S* s) h( L
    3 U/ g3 S9 \7 F4 ~0 X4 v
    正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
    + A4 I# k' `+ N1 B. }" a2 r& i) @
    正则表达式是用来简洁表达一组字符串的表达式
    % n" p' U% p* Z$ t; i
    8 q3 t; e! R9 T6 l- R) Y7 l8 D通用的字符串表达框架. v9 y3 f; }0 o( e( z( t& h

    , @( k) Q- S2 P" w简洁表达一组字符串的表达式8 c; s. V3 v7 p5 P
    7 D2 l! z9 t6 o9 U. ^& n
    针对字符串表达“简洁”和“特征”思想的工具
    / ~- `# b4 w4 b, y. m) ?
    / d, w, P2 Y) z$ `判断某字符串的特征归属
    + R5 G! b, k) X& ?2 T9 r* Z, }! E% V/ ]5 D
    正则表达式在文本处理中十分常用2 K4 A& O$ J2 v1 U) r) V; R, e! T
      N. u9 v0 T/ f, X. K7 r4 R
    表达文本类型的特征(病毒、入侵等): W; y! _% l8 v' A& x
    2 @5 ^  n% ?) s3 B8 _8 v7 w
    同时查找或替换一组字符串7 B2 E# s7 V: `( d3 L3 G8 U4 ~) t
    $ |6 ?4 \$ b% _
    匹配字符串的全部或部分! g0 I- \0 \% q! ^( q

    " }7 R9 T. `; @% C正则表达式的使用: j' [9 U. Y( T% D( ]9 H) `; }* g# J
    - _) M( u0 K; n6 V' d% X3 R
    编译:将符合正则表达式语法的字符串转换成正则式表达特征
    + f% t  L; N! c. j8 \: {5 b5 `! Y3 n# T
    , u3 S1 O% F0 R$ K* Y6 k
    2. 语法+ w' b; K# i8 D0 ?

    " [. a3 H# q- w( t- J5 ]9 n% V' e正则表达式语法由字符和操作符构成
    # }7 [2 k7 ^$ x9 r% }; s$ d6 G( H' |0 |- ^& t! I, M0 S3 R
    有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。! [2 p/ ?, w8 ]" J7 p
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )  j. S+ S3 _9 v
    正则表达式的常用操作符( r8 w( u- M# G$ I* ^5 ]* O
    在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发5 u; ?, {% b3 H9 V7 r
    操作符        说明        实例" k) `/ e) e% S- H) `- B8 _$ D% ?( g# m
    .        表示任何单个字符(除换行符) 【注1】        1 I9 d: _7 c# e# @2 r
    [ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    $ v3 [' Q/ k# U5 v7 y[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符
    7 s4 N* _" k) D* B* ~, w*        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等
    + A9 V& L8 m, i+        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
      ^: @# _0 [: c) S& f?        前一个字符0次或1次扩展        abc?表示 ab、abc. D) D) Y+ I4 x1 @. Y+ M( Z
    |        左右表达式任意一个 【注3】        |abc|def 表示 abc、def7 W# h3 j8 T' w. n$ q+ R
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc" j7 \0 R; K9 G1 v! C
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc2 i2 d+ u( j6 I
    ^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头- s* N  l9 c. n6 k4 A7 j
    $        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾3 u) Y4 |& ]3 b
    ( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def
    6 ]  `7 H1 z6 b' b3 i" f1 q" g\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u7 h% s" z& N1 J+ T* i) E' @6 T" Q
    \d        匹配十进制数字,等价于[0--9]       
    1 C9 n, W) {: G% Q0 O0 {\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]        8 p! w2 s% G  x' ?* g' N
    \s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]        6 O- m* g* K7 g$ H# [5 L; ]2 i
    \S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]        & N% J* e0 \& ^: ?7 P& c+ a
    \w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
    " K' L- [7 X! k$ I% c: Y% h. H\W        于 \w 相反       
    4 {; O8 `5 R! I! q  k# d\b        匹配单词的开始或结束       
    0 J8 L1 Y# e" H$ s( E\B        与 \b 相反        % X7 _6 o/ |' _& r) y* }6 M
    \Z        只匹配字符串的结束位置。        ) N6 Q& u4 o7 S/ C7 e
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。! u3 D0 F. m# Y

    $ ?- ]6 d! G. F! s/ m$ g【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    ' B* ~9 M: ~# Q( V
    2 N1 `% O, Q) o  S" M【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
    ) D% t: Q) m( i6 T  |" B4 P" [, c7 t; k) }
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。: x! a+ Y: N4 i( c* ]0 I7 r
    2 F& b; v. y/ U9 m( r/ T/ B+ D
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。
    ' Z; ~$ p2 K" M) F- o
    / |9 O2 V5 P9 ^. g7 u' J5 u+ s3. 部分元字符应用详解
    4 m7 [! h; U/ p0 T# w) q
    ; T0 N1 s8 i0 S^
    1 H) B) g% A6 J1 ]# j# q
    : w) r4 r6 W9 o( L4 N匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。  k: J; G8 C) k0 [) }( y( R

    ! x& V4 i* l, s, d5 L( l举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
    % \- R, W- J1 I  a$ M* \. R* V: }
    print(re.search('^From', 'From Here to Eternity'))  
    6 r  o, K$ K! ?  u7 P+ y" `+ uprint(re.search('^From', 'Reciting From Memory'))
    6 G5 }2 Q) u- g2 R4 j! @6 |1/ P3 M* ?" R( l) I; `
    2/ R0 I0 u6 i. M& P) R( d7 A& W
    结果如图:
    2 ^. y3 A- {) `: j4 h, f2 d; Q5 ?& o$ F

    / j8 l7 u7 m- Q# H$( t+ x& s' B" l( j5 a# a8 y( _

      X7 q9 K. i5 \# l  D' |  o9 {" w匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    / N3 |! J% d. y% E8 p: r1 H, b$ |1 x3 ^$ n: A1 U  Y( V/ G
    print(re.search('}$', '{block}'))  
    2 ]  f4 N' s! ]1 q% Q. T2 x+ p
    $ X" f1 a/ z; eprint(re.search('}$', '{block} '))
    : i; V+ D$ ^1 L& {5 W' k
    - n( i1 w1 D9 U+ _8 e. d0 }print(re.search('}$', '{block}\n'))  
    9 S0 k; }, p7 ?  L! \3 v; ]1
    8 x! Y2 l9 X) Q$ `: G+ e1 D: n* P2
    1 R* q7 r4 k; t. B3. Y/ Y2 v  k3 a- ]0 K
    4
    7 L  w: n2 t/ p- l9 w: T7 m2 p6 h5: c, C. H2 O! T5 u
    结果如图:- x4 O8 Y, }; d3 p+ Q" V% U
    ' N! A- ^% c7 n3 ?9 ^9 j/ K

    & U; ^& A0 O& d7 p
    / _' g) c3 F. V; n: N9 V) v% o! e同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
    ' N, M+ Q1 k6 V$ y; h
    $ Q* Y7 x' ]+ S: |\A
    5 f5 ~) f% F' R" T6 x; \" \1 S; m4 ~- P0 K# P- v- V0 f
    只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。
    ( H8 z' A1 f: D3 g
    4 ^6 N. p& A$ V$ @1 @. [5 V9 d\b* v' Z- V  ?1 P) O# I

    5 K, @0 x( l9 x, D# I  X; i0 a单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
    7 U. ?* `+ F- R
    4 i) ~4 E3 @! `; L6 [$ x零宽断言相关信息请点击零宽断言查看。  g# F+ {: ]( \6 S
    . X  s% P: d, r! _
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    0 n9 h, C( y' U" r. i! j. ?* V* d' |" n0 ]9 l* O
    p = re.compile(r'\bclass\b')
    " Y1 i5 h8 g0 P8 c6 Q% qprint(p.search('no class at all'))  
    & P7 U" S9 F2 G3 u& ~/ ?: Y( Z3 j6 b
    print(p.search('the declassified algorithm'))
    & W6 l2 A1 I: T+ M/ f4 ?  d$ t4 \! U* p/ V1 H9 R
    print(p.search('one subclass is'))3 a1 r" [4 r' r
    1
    ( P3 u+ M5 S; e( v. C9 Y5 _- A23 y/ D/ J3 `6 H4 a% q3 n
    3' P% r& H* B: O- n
    41 {4 H( T; g2 j% D
    5  S6 N! w4 w  b; v
    6! y& {4 B4 f' K
    结果如图:7 [. ]; v& z% q; W1 t$ ~7 u

    0 m( M( f" a% t8 t在使用这些特殊的序列的时候,有两点是需要注意的:  }2 e- w' @* R6 K' U
    9 d( R& r: m: q- i0 [) g. o
    第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    * T: Q" x2 ~4 C相关原理和解决方法点击详情查看。$ P. J* @2 V# |4 H& M2 K7 w* N  n

    4 W' r- y( |6 j0 z# O9 Q! `+ g0 V第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    0 l8 S4 ?" U; ^* s' |4 K7 @0 S6 C
    3 Y! t# I5 [: T\B
    ! u' E' o& E( ^/ ^& q4 o" [+ t
    ( ]7 _7 n/ H, w9 V" j另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。; a2 F4 k$ k0 i9 {! Q" X3 G

    5 P  x: T  S- s0 J3 X2 O3. 正则表达式实例0 r8 Q3 I2 O! c0 \
    # W5 f) @7 {! [; F8 B, ]' ?
    ( g5 u3 P5 h! l2 O7 J
    经典正则表达式实例# a  h; n; P. B  v
    9 f! w/ l* a: m% W# @3 W
    匹配IP地址的正则表达式
    7 R& s3 N2 m5 U4 Y
    & ]# m+ I( S# t" D6 I8 j- K& a9 WIP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确% ^; s5 F: x, _2 `6 U5 f! U: f1 @

    ' D& W$ E. Y$ z' P6 H7 Q精确写法
    9 ]. b2 `2 b( ?- V6 n+ p2 F7 H) g; ^; ?8 \( |# r8 v1 ~3 `
    0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]
    1 W3 [+ k* z1 ?# q1 p! x(([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])5 h  t3 {/ o0 B5 `* A" V$ H* N; l& U
    原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177
    + B9 V, M4 p# E" ?3 w  Y
    - m) q. W+ `4 d' M7 Q- X" M) V' b7 N( Q' B: a
    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:43 , Processed in 0.588200 second(s), 50 queries .

    回顶部