QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3325|回复: 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
    ' R* c" Q4 k9 Y. U
    Python爬虫 正则表达式应用详解* ?1 V7 j% d' p6 D6 O2 {+ {

    : \1 d" T& H+ ?' b0 Y! O: N学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
    6 S8 ^5 h. K5 ~* n( F' c: J* L8 e, V" ^  H3 y8 G: }8 A
    —— 正则表达式应用详解 ——
    1 \3 {( g6 w4 o0 I* T/ U2 x% c, @3 B- c% h
    文章目录
    6 x! K) M5 m; F4 e) N1 f& }9 ~2 Y" T2 D* q& Y" v7 n0 Q9 N( v0 ?
    Python爬虫(二十一)& [7 H8 V+ Z. \4 B# f4 `9 [- T
    —— 正则表达式应用详解 ——4 L: T: p- b) D) L5 c; @5 w$ O' k, h
    1. 简介
    ; ], _' B! P; g, ^: r& P& o2. 语法
    0 W% i7 N  t( S1 ?4 K3. 部分元字符应用详解
    1 L& s/ P! l& |8 C0 k^% ]  X- V, U; P* {0 `, n
    $
    0 J6 Q, n% Q# Q2 @\A  S+ h) g4 z' t8 L% S
    \b2 P; p* z( f: w0 X2 c: h
    \B7 s! ^) b# t) L  h. e; l8 x
    3. 正则表达式实例
    / Z$ W7 h- l1 X& R  N& H相关文章:
    0 L# V4 B9 x' W  h" a: G  ?; t1.Python的Re库应用详解(正则表达式的库)
    * v  L+ L. k1 U1 I2.Python的Re库与正则表达式的细节解析(正则表达式的库). V& `9 s. p+ L8 Q5 a; S" A

    $ U  s) F; o# M$ D) R1. 简介5 x7 J8 R2 G. n6 H& z+ w" t2 s
    . p: y2 r/ K7 ?, m; c' T
    正则表达式:regular expression,也称regex,简称 RE
    * j* z: l  o8 p% e8 M# ^+ D, X7 |% c1 v
    正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。+ t; @/ ]3 y, H/ [

    ( Y! F3 S  Y+ h0 o3 \; I正则表达式是用来简洁表达一组字符串的表达式
    " K6 q* {+ f/ i9 d5 v! o, @+ ]6 U7 P; m! n$ a9 s% h' ^
    通用的字符串表达框架2 u$ O3 p& z) J7 Q: r+ X

    5 ^  ?9 t# t5 n4 U: y5 ?简洁表达一组字符串的表达式
    9 v$ K1 Y, W  h" N7 ?6 S% _9 C0 S5 x: K+ W) a" K8 r, F2 t* L
    针对字符串表达“简洁”和“特征”思想的工具$ h0 l5 x( e1 ^1 W8 ^- s; b
    . y  c/ l, a, j$ c
    判断某字符串的特征归属
    , h, C" W8 R' a) ?7 A; y- k, e$ c/ j$ b
    正则表达式在文本处理中十分常用
    & e+ f& X  Q( A$ N* d. o! W$ Y8 [; ^) A1 v, y
    表达文本类型的特征(病毒、入侵等)9 p) C8 f+ j7 J) F# r8 @
    , m- J$ A, e$ P
    同时查找或替换一组字符串# V8 D: d7 F% L, s2 }
    5 R: \% u  \4 M+ {3 h
    匹配字符串的全部或部分8 t$ N) @% i% M+ D/ B% h5 N. c

    0 C. Z1 g+ R9 c正则表达式的使用
    # j; I5 z/ Y+ q$ N6 i1 z! T
    4 e- V0 r9 K' B. m8 B6 W$ J7 ~编译:将符合正则表达式语法的字符串转换成正则式表达特征% p. l" P+ ~+ ?# ~6 H6 c" {) v
    . S  Z, v6 W7 W4 J" T* L8 q

    9 d; j- X5 z" X6 @2. 语法
    : }( p7 S8 n4 ]9 S+ D
    6 G& }5 t" R$ P# g* p$ y) Q正则表达式语法由字符和操作符构成
    6 A: @0 [2 K& h$ b
    * h: q* ?3 _' F* Q有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。& S# E5 y& h% i* a
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )6 C0 A( w# u: V! R: f
    正则表达式的常用操作符
    5 |; D0 C1 e4 Y( j' J在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
    ! @: x% K+ d1 c$ T# |4 F% a操作符        说明        实例6 Y/ V3 k& V+ d
    .        表示任何单个字符(除换行符) 【注1】       
    ) e: a+ ~; U( w0 \& B  P[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    ( D/ \, V2 a* E3 a; e[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符
    # j! x5 N8 k1 x# ]2 Y*        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等
    6 q" S% y2 F2 e" i+        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
    ) a# t% B& h( s2 U0 f3 q?        前一个字符0次或1次扩展        abc?表示 ab、abc
    ; P$ Q( y3 O. E8 X! t- {2 _|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def2 d% |3 \- X1 {$ x2 ?+ Y
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc
    4 o3 b* P  Q5 K, g{m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc
    / a- w3 o  T& S7 I) }* t0 z1 r$ E^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头/ I# M* v* B0 y
    $        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾+ o& D7 k( w7 A7 r
    ( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def! N! c0 Q( @% o
    \        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u; K* @: @$ I: Z4 Z: Y6 _2 I
    \d        匹配十进制数字,等价于[0--9]       
    3 L' t9 u* J; y( L. V\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]       
    9 L4 H: P9 D8 v+ U2 N1 U\s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
    6 Q- H& d' `3 v- z8 x% w! T5 G\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
    + C; b# I7 e8 E) z! M9 g8 p- }\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]        8 g1 b% ?8 v  J) p1 H7 K" ]
    \W        于 \w 相反        : e' u- R8 L! k, u1 w
    \b        匹配单词的开始或结束          F% b5 V  T# v# m4 x  }
    \B        与 \b 相反       
    ! U( W4 `7 q3 r* Y4 y+ f% d\Z        只匹配字符串的结束位置。        5 L5 k+ ^' x) V2 X
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。2 _3 f( ^; i, N; I9 J  _3 f/ |( i

    " J" L5 D( X( F0 C* u. V【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    6 I( R* p8 t  g( I7 h6 Z. q
    + p! N: H' u# I5 q+ B& w【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
    , A7 \) L* F, ?# F! H1 e! K# ^5 b1 }& `" L! _
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。
    ) a0 w7 W" ]2 O  \! k2 d0 v9 F3 b# C" G
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。
    . Q' u8 z" X* U; e. h: p; `9 l- p" M
    & K: v1 M1 M2 C0 u6 \4 k3. 部分元字符应用详解
    9 H0 M1 ^1 T1 J% o) q! c4 Z0 {- I+ H; B# ^6 E7 s
    ^/ A. ~# J8 j( ^  B5 D! O8 f0 y
    0 q. f- e- c* d9 M- M
    匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
    4 h2 U5 {9 {, ?, Q6 U
    : j6 F# u/ j: l1 J  ]" c( y0 J' e举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
    ' w7 v' z1 ?: X+ p" J( W3 e" A* ~- E4 J/ }
    print(re.search('^From', 'From Here to Eternity'))  ! |0 [* n  k, Q$ j0 r, v! {+ m: f
    print(re.search('^From', 'Reciting From Memory'))' R. s; Z/ b' y
    1
    2 ^9 V+ N: o- ~# j8 c4 T/ p1 K& a25 Y+ |# I( h5 u+ H6 z$ w5 G" }
    结果如图:5 q" {# `. }# f% I' `

    0 N* A, |) R8 o5 O. l, e! o8 D
    7 p* Z8 t2 f9 i' z$& @" G3 D, ~) e: z& T. O

    4 I4 r8 L8 I0 o9 j+ x匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    5 ^+ D+ N) y! c. Y
    8 W  [" P3 _" m, K: l) E3 tprint(re.search('}$', '{block}'))  ! |& t) U" \, `, D& A
    ) p9 o* l- |/ c" ?
    print(re.search('}$', '{block} '))5 Z4 E6 r! C8 r6 h

    * _1 E0 @4 t$ k; U# Cprint(re.search('}$', '{block}\n'))  
    7 ^) ?4 M+ @; `1, [4 d+ {+ _% O+ I! U- q
    2
    , _' u, Q) w" @" n& H9 A34 v, d" F7 f) t
    4
    2 }6 J2 G$ f+ f" m" |, l5 g5
    / `  r( [/ S( X7 Y* |- j% e结果如图:
    & K: I, }0 N- }3 T7 L' D& X% P6 E% k2 B
    ) J5 Z8 `: O& D4 \, O8 K1 X
    0 ~0 q; E2 c7 C! c* p. v
    同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
    8 d5 P4 I- W; S! `) B, h9 I" h3 W: g/ `  u# p8 a
    \A. q) n0 [9 h( L% f0 ]4 |
    ' W4 U' T2 {" l; r: U8 q) H1 h8 E
    只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。8 h7 a7 a: {$ V* o: F

    ' [) J- m, x2 X# E" y  R$ {\b, J7 D' p1 u. u; X5 c& v
    ! @' H  ^% \# O( v  J, S% C
    单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。7 {; ^* J1 G. f# e/ F) e
    ) ^) b; Q  A. z  R. I" v
    零宽断言相关信息请点击零宽断言查看。8 a5 z1 _$ w% H& s! p  q9 y
    - l7 ~7 y1 o& w+ l; J5 y
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    $ Z& w! G1 {1 m5 |* @3 }( B0 c- R+ K9 C. H7 A
    p = re.compile(r'\bclass\b')
    " s- r, t- o; B3 J( {( Cprint(p.search('no class at all'))  
    2 H* I5 P0 ^# w% d9 P# n2 [5 D2 E  F. }: f: O8 X
    print(p.search('the declassified algorithm'))7 q9 U8 F7 z! U9 }% Y+ O! G
    " e2 `8 N% u1 T  f- e. g
    print(p.search('one subclass is'))5 L$ j* v0 t9 x2 e# q4 e4 Y1 x
    1
    ) O9 u' u, I, W/ V& N- I# B2
    4 R, {) u5 X8 p9 E- M! C- e& A3
    & ~3 I! ?$ I; W" {- ]4: l, p. w' ?1 s: s
    5* D. w( q& \# X7 k
    6
    9 d" `0 e6 Z) G, ?1 t结果如图:1 I4 g  v! M! j5 L8 [0 M
    6 i' a, z1 h/ L5 Z8 U3 G+ O
    在使用这些特殊的序列的时候,有两点是需要注意的:0 |# S1 U/ j- n1 j% `8 A. P3 z) m
    ! }3 t: V& [- f5 [
    第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    / X& |8 z$ G$ B; n. R相关原理和解决方法点击详情查看。
    3 M( i3 h- ]" V. u% }+ J( v2 W& E" K9 `8 G! ]) ?
    第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    ; F& l' p) u$ n- z% ~6 I
    & `  u& H/ ^5 O% A1 T\B! C" o2 r/ D. Q" l+ O
    2 L' U2 E3 n, G* r" h
    另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。. n3 @$ O; R+ L4 w5 e) U* {* e7 u: X
    , q  Z: O% ~. W( i
    3. 正则表达式实例4 a6 m% N, q4 d( `
    ( C8 b6 F& w/ `+ F$ s0 M, g

    $ m/ ^7 D0 l" Q9 l' i& W经典正则表达式实例: `4 L3 C' d: I( A# i

    9 m) ?( L) V% s9 Q匹配IP地址的正则表达式
    1 Y' \2 ]( X1 t6 p# }
    2 c0 Z; S7 ~# j" eIP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确
    7 u" [) u+ j! {% u9 I# h3 ~* s6 N. |+ C$ `, j5 K6 t! T
    精确写法
    4 K+ Y* Y7 L+ n( I2 j2 z5 w* T
    4 d1 S/ A2 }* O0 E& w$ b8 J0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]0 N& O9 x' m/ o* I/ r6 I/ |7 K  M, D
    (([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])8 M6 X4 f! c% l) ]4 V
    原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177
    + H2 G+ f$ O5 u7 x& H* M
    5 o, ~9 v' ]: g
    6 m0 t; E2 P3 m- l' L
    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 03:22 , Processed in 0.432113 second(s), 51 queries .

    回顶部