QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3279|回复: 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 V* o, z5 e: e& mPython爬虫 正则表达式应用详解
    " e/ j7 B) }8 ~7 ]  {/ y. m% g/ O& [
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。8 t8 L/ w4 {# Q( E# k
    / p% _: b) l6 N. o, D
    —— 正则表达式应用详解 ——
    : b- t; h2 j: E
    3 V0 g& T- ?/ Q! p0 l( `. V( A文章目录
    * ~6 ^% \% ~$ Y) f1 U) z. L) k9 T' k( @+ N$ f
    Python爬虫(二十一)7 a" R/ u+ l$ k7 ?3 T
    —— 正则表达式应用详解 ——; V( ~/ E) g. t0 z
    1. 简介$ K1 Q. q% L/ M7 I% q  X
    2. 语法
    6 n) M( M+ s: r% `6 g, N3 }; Y0 O3. 部分元字符应用详解
    6 ~4 l% ]  [3 x^" Z9 J' g0 p% Q: l% Q- A7 c
    $  s$ @6 E% \0 r) d/ B
    \A: M  I: G" o; j, D8 |; }
    \b6 D2 s8 i# G. z& U! L/ z0 S" z. [
    \B
    : z8 T6 I! U+ o' W3. 正则表达式实例
    ; I9 T/ ]! m7 }) A9 l: r相关文章:- ^8 a2 o* d3 N4 i( J4 _1 r0 \
    1.Python的Re库应用详解(正则表达式的库); N5 o# F* H2 Y  _, U& }( r
    2.Python的Re库与正则表达式的细节解析(正则表达式的库)
    4 Q5 \7 ]2 [- a" W8 j# ]; @" w" \# |
    1. 简介
    4 G" z  m7 z$ F9 e. k: B4 R9 I6 F) @; l3 R0 Y7 e3 G2 K* q9 I6 k+ L
    正则表达式:regular expression,也称regex,简称 RE% Z3 @: \0 \0 n7 Q% I* j
    # U. X, s% l) H
    正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
      f& R9 y: \$ l" n
    0 Y5 V8 m% b( I9 N% L* I; \- g- `# q9 b正则表达式是用来简洁表达一组字符串的表达式
    $ X, c, k6 N: M. j+ l# U8 h7 p8 H* j4 n* i
    通用的字符串表达框架
    , X- B) f" V( {  H  V6 n  a( w& V  D0 V
    简洁表达一组字符串的表达式
    5 e/ E. ?. Q$ E. _+ T6 j  X4 [2 E/ ~
    ( r! M7 |6 P6 Q; v针对字符串表达“简洁”和“特征”思想的工具2 Z9 ]  r" A7 D+ ^- a9 ]
    5 R  N5 D' ?  N2 m* e; l
    判断某字符串的特征归属
    8 D2 s9 b' D  g
    6 h8 V# u$ K5 a- s正则表达式在文本处理中十分常用# E3 u2 u8 o" }1 c: W7 ?9 S: @
    : l. E# \8 s" Z
    表达文本类型的特征(病毒、入侵等)& O/ v8 q& @/ A  e+ z: j

    - D' K2 R! f- k1 _; b同时查找或替换一组字符串
    / H5 A: J+ ~5 C" f4 N1 X6 \% p& o3 R/ W+ m+ A) f' ]
    匹配字符串的全部或部分6 l/ w" ~) ]6 Z2 I5 k  _
    0 E" a7 S" X: y. V+ p" }' `, m, E
    正则表达式的使用
    3 v  l  Y3 ~* g- x' _0 p6 e& c) P6 x  `
    编译:将符合正则表达式语法的字符串转换成正则式表达特征* P; t4 f/ y/ S
    & F- K! k3 \5 ?

    8 Y" A: G& {1 S& ]2. 语法
    . S2 U$ ?4 e: C2 V/ D  m
    . y$ C) v. o4 N$ z1 D正则表达式语法由字符和操作符构成
    0 b& R4 N+ Q% r2 a) T' g5 L0 i$ r2 q, s3 T0 O/ G4 b" Y
    有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。
    & g9 l9 L7 B; h% v) Q元字符包括:. ^ $ * + ? { } [ ] \ | ( )
    6 e( P3 `! S& }# O5 T正则表达式的常用操作符
    ! {3 R( E/ _' s; v& N& l  L在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发1 V5 ]& ~3 A: r/ {
    操作符        说明        实例- t: w6 w5 K5 b: m: f% B
    .        表示任何单个字符(除换行符) 【注1】        . T- M) I8 {% T6 F! o0 [1 I6 |" b
    [ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    + J+ g) q+ ?3 L, `# ?: q[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符6 x; f$ G- f5 n: d+ b; X4 p
    *        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等& ?' d; s' d& d0 Y
    +        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等  o& T9 J. t2 E' x6 c3 m+ h9 s
    ?        前一个字符0次或1次扩展        abc?表示 ab、abc
    ' h% i$ L  c+ r% q|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def
    9 f4 T$ J. y5 O$ v{m}        扩展前一个字符m次        ab{2}c 表示 abbc6 q! D3 {2 C( e0 k4 `8 }; O
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc$ x: q2 t& o/ a2 o' I, n+ B1 ^
    ^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头& v# j$ H6 d/ h9 U5 i" v. w
    $        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾
    . y- N5 o, x7 G( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def
    2 i  k$ K/ e# B0 Q\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u
    - l) O$ \- x( L6 Y  ~\d        匹配十进制数字,等价于[0--9]          [  {) Q/ A' U  j
    \D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]       
    / M+ g# g: g6 o- U6 e\s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]        ' R- F( r( f. X0 I
    \S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
    ! v5 x) w" q% I7 }\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]        9 m; e* `* X* [# o% W0 S3 _# R
    \W        于 \w 相反        * s) Q- I' Q' ^6 [
    \b        匹配单词的开始或结束       
    # j) n4 [% E% M! E+ s/ j2 T; D\B        与 \b 相反       
    2 Q8 B& O. n8 z2 D- z\Z        只匹配字符串的结束位置。        * n/ U' ^# X& t# ^9 `5 D- C7 m
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。; y, w* Y2 @% y" ]& `
    ! ?0 H7 u/ |! t  t: M" Z
    【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;* |9 F0 j6 l( \  {/ k& _) V( ]
    - Y! a3 N) V. S7 K6 r4 [- O
    【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。: X" D/ d& n2 E2 X
    4 z4 i; h' Z/ ~, a" {- `1 f8 B
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。5 B' l; C( k8 ^1 W
    4 x* Q5 I7 N! s1 W; J) i, l$ n
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。' A: u: n! Y$ Q

    " m, M1 C% i& K" W" o3. 部分元字符应用详解2 _* }% Q- o8 ^" N0 K+ Q) ?

    ' }6 P+ B& e; E% t8 K: x^! e, d& m/ {/ }9 U7 E$ V

    1 J4 e4 r% i; q, \匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。# B: _1 C& C9 g" H% L+ ?0 C

    : I' ~; @2 B7 L9 t, G1 h' v" o举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
    ( j! \. `8 u% p; d8 m
    . ?& {. B, }  c/ Xprint(re.search('^From', 'From Here to Eternity'))  9 W% k2 I7 `' r! z1 Z+ H
    print(re.search('^From', 'Reciting From Memory'))/ M* c& X5 ~' O; x) R9 |7 v
    1
    $ l1 ]% I- }5 |0 D2 F28 y3 C6 ^: `0 b- S
    结果如图:$ K9 @4 d7 c! m: ^- g% S
    5 z& c" m9 g. Z5 |5 a

    % W! u' a# z; Q9 P  _$ `$% u, A% g& D2 L* d: o. X+ N6 v7 Y
    - b7 s8 K6 J6 _! |
    匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    " |9 }9 k& ?3 S& z' q% Y2 l6 u: t) ^( ?! P3 q- S
    print(re.search('}$', '{block}'))  7 y" J4 b$ E4 Q; v
    1 M( k3 y; ?; |, e$ O6 M: o$ [
    print(re.search('}$', '{block} '))% @6 b7 H7 s1 o6 I
    ) ~; {/ p7 \4 h; Q6 V4 Y% j6 y; X# G
    print(re.search('}$', '{block}\n'))  
    , @8 N( l$ ?) R1 O* @, e/ k13 X; K6 B7 j( s0 \. B# ~7 ^4 q! j- |
    2" W8 \, Z3 k" b' |( ~( |
    3
    . `  q8 z; G3 O: F, q4
    6 h) d+ Z( D$ s% F. q4 u" ?! @0 i7 Z. F59 m. q- ]) ]0 M( @  `% v! {4 H, R! e+ V
    结果如图:
    8 g- s' O  `- u# z3 @
    ; D/ E* s6 g& M9 B8 A
    ( J5 C7 E* ?/ w# J3 w' Q
    9 Y3 g0 I0 C1 z4 E$ G同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
    ! f& A- C: }* |3 p  u
    9 _6 B# y% b0 K" Q2 h7 f4 L) ~! W2 N\A
    2 d2 {' @" P% O
    ' t* ~7 T; O+ w/ H只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。
    # v* D: S! L! L+ O+ N$ B7 ?* ~- D# ]1 ^, K
    \b( t/ h6 k5 v: A5 `
    5 x( E3 r# i+ L. l; C
    单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
      _* f! c4 G* v' ^0 c: c' e
    ; S6 i6 r; ?3 W! n! h零宽断言相关信息请点击零宽断言查看。3 H7 e7 h6 [; g) q* y

    2 Q8 h; o- E) o0 p% `下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。" Q9 L% P/ k: ]& w) @) v  N
      _3 w1 k( G4 c6 o, `0 ?1 a
    p = re.compile(r'\bclass\b'). U2 y, l$ r+ N( I& M- ^3 Q2 b4 x+ G
    print(p.search('no class at all'))  3 d* a; v1 U3 t* R7 z6 n2 ?- k$ Q
    # I6 X8 [" y  W
    print(p.search('the declassified algorithm'))1 F* Z0 }" e: t+ m* Q7 H

    7 u! Z7 w' C8 U  z' Y% h1 Iprint(p.search('one subclass is'))
    2 r; N$ a- d* Z7 P" m/ j1) H6 ^0 u9 k! t0 L  C# e
    23 c1 v2 d& r! X$ x) k! i
    3
    4 J# G: s& d, B0 S48 ]8 g( R1 T/ X! n
    5/ E' e$ t4 S- r- {" K
    6* Y( G  p, C( a0 w6 n) _- b
    结果如图:
    & x2 y# |1 W1 C8 ?
    " N) z1 M! |' }( C7 k2 k在使用这些特殊的序列的时候,有两点是需要注意的:! {# m3 ^' Z2 K" y

    - L  b/ U. Q$ e; L; B第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。- F! z" m. t! R- R: N
    相关原理和解决方法点击详情查看。9 A+ o0 `( q- [6 t+ M4 ~" L# M, t
    6 a7 p5 _0 @$ i2 t; B; v
    第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    + J( z; [1 n) Z, _8 s  s8 K
    * ?" q5 k1 X- F' Y. F' x\B" v- _$ c  B! D. I) k
    3 w8 t7 R. o6 k% }3 C! F
    另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。& g. m, ~' K1 C' Y1 O

    6 O4 a2 u, W! ~5 D6 F. l3. 正则表达式实例* _" @/ U6 h* v! g7 i& k# Q+ c
    + A$ U( `3 Z" ?5 v* o

    ' o! N  {4 o* i* {经典正则表达式实例( A( P7 u( ?% A1 l1 r

    ' S: j/ {) S/ Y& \匹配IP地址的正则表达式0 `9 H; O$ C& n3 M% N( i/ I
    " z* N! G" n6 h0 Q% V' J+ I
    IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确) F8 V2 z' J- [% a3 @7 u6 V

    3 y8 L8 Z9 }3 ~  t+ m精确写法
    : H; [0 p" W. J% \
    % V9 `7 ~# q. S  i* v5 T' P0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]3 G. v8 _: T  A$ k
    (([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]), J5 S3 I& C9 G( z1 X) E, I; ?- d
    原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177# c* M2 M  ^5 F$ i) i% \5 w9 F

    - d" m( K: @4 V: ?0 w3 y/ c) Y8 q2 t( Y2 Q
    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-6-2 23:52 , Processed in 0.369344 second(s), 51 queries .

    回顶部