QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3328|回复: 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 e& Y" f1 M2 \
    Python爬虫 正则表达式应用详解
    , ^/ a4 q* A' P# ~0 d' D+ @, A$ A" p7 |# O! D6 Z; t
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。" U0 t  v8 ^+ C: R6 i/ {1 w
    " _. t; J9 N1 K# j$ Q9 M
    —— 正则表达式应用详解 ——
    1 P8 J9 E* m2 t9 ?* |
    " g0 m  T* F& h. a: f7 a- t文章目录
    - L- g# I9 q1 Z! n. V- S9 h
    / Z& |2 B  p% Z; \; ~Python爬虫(二十一)/ w3 m! U, L/ d+ q2 \
    —— 正则表达式应用详解 ——
    / c3 L; h+ l6 G- z1. 简介$ @8 v  H2 ]" {2 M6 Q! M
    2. 语法) T- ]6 p" s9 N0 ~, H
    3. 部分元字符应用详解, G6 F- l8 O. H
    ^, l+ I1 {! I- ~+ B& {  g' d
    $
    , X- V5 H) J; t! S* p' u$ F\A5 I; \* f' H% N9 U$ L
    \b' D9 B$ R9 B9 a
    \B
    ) k8 L* e2 W; b, V- d" M! d9 S% s4 s3. 正则表达式实例
    ; A( M7 ]4 e4 K6 e) o相关文章:
    , }2 @2 ]2 Z. W$ ~1.Python的Re库应用详解(正则表达式的库)
    8 [" M& l: Q; ?- B6 F8 X2.Python的Re库与正则表达式的细节解析(正则表达式的库)) U7 l4 o: }4 X! V* q# A; Y5 I% y+ a

    " \9 C* h# _. }1. 简介% _) L7 S  `/ Q# `, ^
    8 p$ `9 P. y8 a* n* R- d3 c- I6 J
    正则表达式:regular expression,也称regex,简称 RE
    / M5 K7 w) v( T/ ~6 P) ~7 v, f" Y" |+ k/ Z+ q7 \7 @& a
    正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。; U6 @# [* _9 r) \# U
    5 h+ L9 U, }% G2 e$ {  r. F1 g
    正则表达式是用来简洁表达一组字符串的表达式# \  m; w/ Y3 I/ |7 @: d. ^$ u. u

    7 `. W* @. @0 ^9 N/ _' X& v通用的字符串表达框架% d6 G- k( m3 z

    * v8 s7 ]# ~0 R0 _6 J3 `简洁表达一组字符串的表达式
    * y7 E1 C6 o1 }
    : G: S7 h6 o3 o针对字符串表达“简洁”和“特征”思想的工具6 _/ J8 @$ U5 `
    : ~, B' k( V: y8 j- f
    判断某字符串的特征归属7 u% f! V$ @! w$ H* u- r& }! q- ~4 {

    % `% ^" U* B: ?/ W正则表达式在文本处理中十分常用
    5 L, R1 l; j& G7 c6 F. D! B
    5 A7 s& a6 g" ^+ O$ W% p! G/ R表达文本类型的特征(病毒、入侵等)9 P' \( u7 ~! B2 T
    & c3 |+ J. e* z
    同时查找或替换一组字符串
    3 [+ U, k$ n4 L7 U2 Z
    9 [% x# F' t8 F匹配字符串的全部或部分
    4 N: D; n3 ]. Q1 a- L
    0 ]8 f2 Q) ~6 m" d1 t3 Z1 T5 E+ R. g- L正则表达式的使用
    ) m% f6 W/ ^2 R9 E# v. k
    . C* v# h6 i5 W! B; x- i, X编译:将符合正则表达式语法的字符串转换成正则式表达特征) z- K. x# c; ?

    3 x3 b4 y$ ~" d* ]; q
      ]* a# Q) F1 D$ ?5 ^2. 语法
    ) V. p) |& [1 c, W+ l/ K  r. I% N9 }
    / v6 r$ ]  `1 ^# j7 k' C正则表达式语法由字符和操作符构成
    $ N- _0 Y4 f) I6 r# H) a! o- b3 P# ?$ ~! N$ @
    有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。; A/ O. \; a/ D3 A2 e
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )
    % E' R* ^4 l; G+ ?; i正则表达式的常用操作符
    # i( N$ m( |0 z1 O) @' T在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
    2 ^  o  F: Z2 M2 a1 K操作符        说明        实例
    ( M1 F% d( m6 T2 i. O.        表示任何单个字符(除换行符) 【注1】       
    ' ?* i, F) E7 ?/ N1 {) D$ J[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    & T2 y0 e3 m! Q; E3 n2 j9 e[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符0 ^8 R2 I0 H; Y& u& f' S
    *        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等; y7 |$ a5 u' i( S* Z/ L& Z- P$ p* w: h
    +        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等3 M- _9 O8 _1 B. c& n
    ?        前一个字符0次或1次扩展        abc?表示 ab、abc- A3 G3 A. F8 S; a  P+ A
    |        左右表达式任意一个 【注3】        |abc|def 表示 abc、def9 K; e; H$ d- x9 S
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc9 w9 q$ S0 M3 J3 ]0 o
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc
    6 ]( r: a" q: C* Q  B# ?0 C^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头
    % L5 d" [; C5 J( v2 B$        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾& s9 A. a0 j. c: k) g7 k  w
    ( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def* i& X' B5 P) T* H8 z
    \        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u
    % A% u1 X0 {0 k: o1 o\d        匹配十进制数字,等价于[0--9]       
    9 R! ^( h; u9 g* Y) b' o) x\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]       
      Z+ Z. r; Y* ~& ^0 r* L, @\s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
    , p0 C0 {" z( u3 `0 V\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
    : Z. I( f# K" D' S\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
    ; e( {* v* j3 d! V9 Y! I$ R$ r5 [$ \\W        于 \w 相反        5 V; V7 L; I5 F( ]0 g
    \b        匹配单词的开始或结束        6 D  W8 W1 I# J* H9 s0 O
    \B        与 \b 相反       
    9 ?/ h4 A) R2 I- r4 l\Z        只匹配字符串的结束位置。        3 r& G# C8 y4 ]3 N4 s
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。
    + r. y4 c, E8 I$ _. ~8 N/ `
    " s3 o, N4 Z2 b( a3 y  W8 B【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;7 A' M7 N) N0 K9 S* f4 [, d+ D
    : h1 P( }7 Q. N! ^# p% i7 B% I/ `& ?
    【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
    8 H  P, K  }' s  j$ Z/ @2 I, {9 P9 M0 \% a6 u$ s
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。  r" `$ N  |9 i$ n0 m* b

    ' P% h# ~- C& w+ t. B1 R【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。* G4 H, K; |2 [4 i1 T9 M+ @4 ]
    3 ]% l# s$ w9 V7 _+ }7 ?* i6 _
    3. 部分元字符应用详解$ d+ W- o! J1 Y4 M( M" V

    / V/ z# n! e7 a^
    ; I8 X8 h+ j% u, i
    ) `: D8 {  X! \+ D! H  @匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。: R( Z- u$ C) t2 ?' z7 p

    ' d: Q3 }% g& |  a7 S举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:/ z# v  C3 B3 m2 s2 L. ~

    " k" W# F7 y8 q' W# g7 fprint(re.search('^From', 'From Here to Eternity'))  
    5 e) S5 G2 `- l5 B: b/ Hprint(re.search('^From', 'Reciting From Memory'))
    ; M6 S# C  q4 K1
    + D( d2 I6 |. l: N* {* ~2
    5 X8 D2 i4 y/ f7 `3 Y( C7 r结果如图:
    7 \4 Q& f: s& P' ]$ A! V( s: y: ]1 p2 s
    ) ^) Q6 D. r  ~" ?+ w7 k7 C( i2 y
    $
    / z& C, t5 ^( m- m. n2 Z. j) Y. j* L. m1 Q& U, z+ e
    匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    + a, o) Q4 K6 H7 u7 F: ~; M' q& ~  E  w6 x; ^
    print(re.search('}$', '{block}'))  
    / y: _+ B  H2 A+ g+ l, [
    ; _. R: z# g- v) o7 ~+ iprint(re.search('}$', '{block} '))) f+ Q# K) P1 K& _) |

      I+ a8 F$ f5 ^3 gprint(re.search('}$', '{block}\n'))  
    ( i5 C8 Z* W( E7 }1
    7 j6 O; P- Y3 @5 M2
    % G/ l3 t8 b7 _) e. D5 {# i3
    & d6 p6 S- Q9 z9 w2 S7 g" n49 b: e& t9 ]# F
    5' N& @4 e% c6 u9 T
    结果如图:& I( {6 M, \4 [

    + \. v" x. P' N$ m! x) s
    . F4 c! e) a+ e2 a+ l, a* L) i
    ! j% l1 g4 J  A/ ~) ^同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
    % ]5 v* F2 ]/ ?3 ^/ u  B, o) D- k5 c# H' ~
    \A
    ( g$ ~! _2 w3 a3 Z5 o* l4 \5 h2 @% z
    只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。8 D: _, s7 v8 l! c) C7 a2 E

    # {& X, E" m( b" }' i5 G\b
    + e$ F/ u: a3 A; k6 ]5 @  W# J- p) I0 T& l' T3 m
    单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。! u+ [/ r# N/ y$ I
    5 T$ v8 l- z9 W5 O1 S+ a# R( P
    零宽断言相关信息请点击零宽断言查看。
    0 o( t* @, m/ @8 ]9 Q3 V4 q3 M1 d! y: Q9 [* s5 L. V' E8 |( I
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    , @* X$ ]1 c7 Y  q$ Z. x
    2 s8 d' x! ]" Dp = re.compile(r'\bclass\b')/ b: O2 H, _  m* {3 D: S" k; o8 F% Q
    print(p.search('no class at all'))  * H' |; C( c1 q: l5 {" v
    ; m8 A( {# r: v3 \; h
    print(p.search('the declassified algorithm'))
    $ o* c5 g5 Q6 g8 s# n: V4 \" }( }- Z' B7 X: S& g$ P: }6 p
    print(p.search('one subclass is'))
    6 [$ e! ?, [& N: k; y1. r$ B2 Z4 {* J4 n
    2
    5 `6 {$ T* V" E+ d3
    ; a6 M& o0 s! {% a. q& T% v  b4! X: z) Q/ a5 j. Z7 s- |& V
    5
    - x* B1 w$ W  I/ F9 l( E6
    - ]/ `3 V. V! Q- U* ?+ u结果如图:
    2 o& [/ o- J  {$ V, n+ |" Y4 o) U; E
    在使用这些特殊的序列的时候,有两点是需要注意的:
    , U2 ^+ J9 i  n! p4 V
    " E* [& N9 {8 L( G  J( J$ \3 S; T+ p. s第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    # z) N# v, Z( \- E$ v8 T% n相关原理和解决方法点击详情查看。1 e2 ^/ i& I- B% k" `4 }9 ~

    $ N+ S/ C+ B4 l/ t  E第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    # Z; J8 U& z  X9 F) Y5 A
    0 s! q+ Z$ Q+ q9 Z\B0 G: ~9 l* b, r8 P  F
    3 U: N2 r9 U7 x! k! h( c+ Z
    另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
    0 f; E3 i& k5 G4 O7 f; W
    1 S! |- t5 R1 [& E" n  P& o3. 正则表达式实例
    ! R: y! _! y, r8 M8 D$ ^
    $ j: W6 w& Y4 Y2 t$ x: i2 v2 F" k% \9 m7 J. ]
    经典正则表达式实例0 r+ u3 }  S( R) B1 r

    4 f$ A+ y, S0 Q7 v4 `- c* H: k, ]匹配IP地址的正则表达式
    5 J2 ^* i# c1 M- ^' J8 Y* p0 E$ S! e, [. h5 p: L* |
    IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确) \5 l/ n# I- k) H7 U% n. {6 N8 J
    # c- {0 `( E0 g* L4 J
    精确写法
    ! m) W: ]- ^  ^% _) D
    ! ^+ o+ W! {' x. V0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]" _, k/ Y5 y' m% I( [3 W. s
    (([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])
    ) L1 X6 r/ e0 d5 c/ F) l3 n原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177
    1 i- l- f) c$ R* r" Q" G; Z& D1 t7 L5 e: L5 a# v! [

    " ?4 m! o" h' n' J; H* K$ 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-3 12:30 , Processed in 0.466996 second(s), 50 queries .

    回顶部