QQ登录

只需要一步,快速开始

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

    4 V7 L" r/ q, {, x# VPython爬虫 正则表达式应用详解
    & F8 ]. K( u3 T! [
    1 o- Y& t" @1 M4 M6 [学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
    : J8 @) r+ S2 |/ f+ l& K) P% K5 M  ~: X
    —— 正则表达式应用详解 ——3 j; F3 Y) l+ J  @0 E
    ; N* _3 k/ o: n) z. _
    文章目录
    " s+ q! a9 e" l* E3 x, ]! E) w/ j& n. O0 E
    Python爬虫(二十一)
    ! S6 \, F: b* h$ e6 j—— 正则表达式应用详解 ——/ M" W* Q  L5 H
    1. 简介/ x+ y- k0 b% E/ R
    2. 语法
    6 M  [& |' N8 ~; Y! B/ A5 `) z3. 部分元字符应用详解
    - c) q- F6 o+ V/ v1 ]5 {! N& n2 x^. ^5 \" O; e9 z! i* V/ B2 n& Z! |
    $; ^  y' Y. e) s! D
    \A4 e! P+ ]# E8 Y0 C8 |( i' t
    \b# y, m" \  @3 o, q4 m' `  E% n
    \B
    0 U' `; k7 {& w7 {3. 正则表达式实例. p  E# O/ x" \, m5 _# h7 p
    相关文章:
    6 _% W" m. y& d1.Python的Re库应用详解(正则表达式的库)
    % I$ m6 Z6 @/ f2.Python的Re库与正则表达式的细节解析(正则表达式的库)
    6 j( s+ M( H" z3 i7 U, K# f% B& Q5 I: _: K1 s, X) o
    1. 简介
    % V9 n) D7 T9 B# q9 p) O9 O* f* U( D' w. T7 S: T/ ?
    正则表达式:regular expression,也称regex,简称 RE
    6 ^8 h* s9 K& [
    & c2 B" L: M& G0 L8 W+ Y* {正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
    : D8 n0 N+ S* e# G; m
    1 f( ~+ ]  r# F+ l2 |! b3 t- Y正则表达式是用来简洁表达一组字符串的表达式
    . a, F5 s+ ?1 A& ^. @
    + p- F0 h2 U+ e# K7 j9 W( s通用的字符串表达框架& Q, e8 X6 A7 ^: A. y/ A: s5 n

    ) h& r% c5 W% ~简洁表达一组字符串的表达式
    " G& S6 |( T' c5 ^2 X% X7 I( l" g1 _9 Q
    针对字符串表达“简洁”和“特征”思想的工具0 e+ I" j0 I3 D! ?! G

    2 V/ S! k7 ]5 f. Y判断某字符串的特征归属
    1 s  U5 j% D0 J0 M/ C: T. q& p; l
    ' R# n2 A6 a+ Z6 I/ i$ i% o/ \正则表达式在文本处理中十分常用' a" H4 s/ W! S

    2 d9 ^+ d+ y- Y& F( Y表达文本类型的特征(病毒、入侵等)
    1 \- X& l5 Q8 X3 W- L$ {" c$ v9 [# y2 p9 s0 m2 {
    同时查找或替换一组字符串( e* q$ H* e2 W* K$ o4 l
    3 A9 g+ ^* K' w! D" c/ v$ q* g
    匹配字符串的全部或部分
    2 H6 Y- X* y# [6 R3 ]# _- H7 c+ L+ `7 |: s7 g
    正则表达式的使用) m) y+ A) k9 n: ~# i+ A* B
    0 _4 Y7 F4 m) m; K
    编译:将符合正则表达式语法的字符串转换成正则式表达特征
    7 V6 L- G+ a0 {' B
    1 X  \) s/ }( }+ c
    % p/ s2 M; I2 {2. 语法7 u- U8 S% j: X! e  \" I

    3 L4 Y6 H  \1 n# z" [正则表达式语法由字符和操作符构成8 \% ?4 y  Q+ ?2 N

    0 I: ?, k2 R4 k% V+ I/ k1 `6 {/ I; V有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。! t2 I" T- K- H8 n' q# n9 o" k7 a9 G% w
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )+ A3 Z- x8 {2 e3 a) m: ~
    正则表达式的常用操作符
    ' Y7 j8 {) ]5 g0 C' A  U在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发1 `6 F6 c* C0 t- q2 h* @
    操作符        说明        实例
    6 d* l( Z) O* ^& C/ [: N) a.        表示任何单个字符(除换行符) 【注1】       
    & B; o! q5 m4 u$ Z; |[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符6 b9 E% ^2 g# x
    [^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符' R* C: u  A; I" {' y5 H& W
    *        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等  i2 Y6 V' |- h  q8 k0 w5 W  a$ H
    +        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等' W% q% k  I5 w
    ?        前一个字符0次或1次扩展        abc?表示 ab、abc
    # M6 q1 ]/ k& J' q|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def. M+ t! _* w2 c! A
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc
    # T2 L3 _3 |/ \* n{m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc
    5 S% W4 D$ i) U; K+ M; a7 U^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头
    ( i2 D/ Z; t$ Q# |$        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾" ~9 q5 F5 a9 o1 z
    ( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def
    / p  R& V+ |5 u. d6 g\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u1 Y9 |. d: }, t
    \d        匹配十进制数字,等价于[0--9]       
    ( F6 ]9 e6 ]5 U4 o\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]        0 Q3 }/ Y% a. r6 W6 w0 X
    \s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
    ; a1 C0 r7 D- L, T! P4 N  _" Z\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]        + H' y4 _7 t2 X$ }; ~
    \w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]        * p$ S, |  S6 L7 h
    \W        于 \w 相反       
    ' b7 g% g: A9 P5 h# m\b        匹配单词的开始或结束       
    ; ^( ]7 b1 ?( o+ ~2 K\B        与 \b 相反       
    7 T0 s. S  r' t% b7 Y6 V( N, W\Z        只匹配字符串的结束位置。       
    & P, v% `/ e; b1 q4 l6 C! _【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。; V, A( Q: \& n, H8 E1 |* \/ Z
    8 |( ]$ A1 m7 x
    【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;- Y+ L+ E& F; g7 M2 U# T# a

    # @: ]  J* T8 P. r, Y+ z; U【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
    0 P2 }5 |9 @0 N( V% t' E- Y: N' L& R* o2 A1 d
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。# m  F9 Y! r( N
    - L6 A. O& ?% I4 R. T2 i
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。# C% a" o2 g2 u8 A, Z

    + n8 e( j" I- M3 A1 {% f* I3. 部分元字符应用详解4 X! b. j8 s) r% `9 m* ~  p6 m: u5 k
    & z+ a7 O8 D# v  Z
    ^
    : e( s& G) M( r( m& m' w$ i; y% e6 I& {
    匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。& l/ X: s$ H" H: A
      Q! P4 {4 P' f, ]0 z( e# s4 O
    举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:
    " O4 `; c7 \: B+ C, Y' h* F4 x
    ' l* J/ `) [' m" q  @print(re.search('^From', 'From Here to Eternity'))  - J! J' D& j& r1 |
    print(re.search('^From', 'Reciting From Memory')): r5 @" K; @6 {: p
    1* v1 j2 N3 s% m$ ^; ^
    22 c! w  j0 W7 B* t- o* G
    结果如图:+ e6 S8 ^6 Y( R* J: w) ?
    ' Z* _' s. P5 H: w' Y' P; u
    5 B1 Z1 W! y% S- g, g! \  }; q
    $
    % J  T9 v* E& s
    4 c; o! I# P% r6 X1 N; c/ b5 K匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    ' B, C4 f. Y5 B1 R3 `$ [
    4 }) v& ^* M0 q$ R( r% L  i( jprint(re.search('}$', '{block}'))  
    & s# q. K! D3 y* M5 N- ?4 x
    : d8 x( z, L$ O- jprint(re.search('}$', '{block} '))
    4 F" i3 |( e: G% o$ C% e
    1 C$ K# j6 Q8 \print(re.search('}$', '{block}\n'))  
    8 t- S% }1 ]& N1
    ! u9 h6 Q4 q& B* J7 _28 E( M' a# N- E, @- V6 C% r
    3$ M+ z/ ?. n3 y; @1 D# |
    42 M( U" s' x8 d
    51 ^; U2 \0 S# w
    结果如图:
    6 U/ @# D( g1 _
    , w9 f+ N% G& `' f5 A$ H- b* T1 U6 ?6 G5 W/ Z& O: i
    " J0 v1 d$ }( I; \
    同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
    % s( \/ c2 Y7 v$ f5 G6 R* F( `) N- V7 D# v9 K, v9 ~
    \A% v2 D+ G/ q& N7 O
    2 X8 I) B9 G: U& K# ?/ K; c
    只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。
    4 ]3 B" Y; t9 e9 d1 c4 G  W. N
    + f0 X$ l2 H# f" U. Q6 _\b
    , Y/ O6 b4 T/ ^& L( _
    . }; {5 z! ?. E7 B1 U: z* ?单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。, B5 k( Z; y  S3 n& D

    # B. X  y: T, I7 a' S零宽断言相关信息请点击零宽断言查看。7 K% h) v7 p, }8 g6 o
    3 C! z9 {2 o0 W" o1 s5 t8 b
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    6 _0 _, P% W9 f; \4 {2 n& ?) j% X3 y
    p = re.compile(r'\bclass\b')
    % h# k% i/ V. j# g  pprint(p.search('no class at all'))  
    8 l, V8 m( {' g" P; ], ?1 T, g, U8 x& ~$ y' o0 `- @0 c% Q. O
    print(p.search('the declassified algorithm'))0 n) V. }2 ?) p, d  i8 s2 |
    ( e+ b2 x: ^, U$ ]
    print(p.search('one subclass is'))& V9 t* A9 ?" `
    1+ F7 e3 m5 `$ \. \
    2& A9 I# A, m( e1 R. ]
    32 {& T! s/ [. S5 p1 V9 ^1 }- \6 M
    4
    & o8 ]. ?" ], I* q) @2 T' ?  y. \5
    ! U% Z# r/ J6 ?! w9 y9 d8 Y+ {6! q) N" B) J3 }. s: C& N0 p3 h
    结果如图:" s' e, F7 ^$ C( W. z: s5 m- h

    ( h" E& ?# i0 ^9 T在使用这些特殊的序列的时候,有两点是需要注意的:
    , P6 _& y; p$ c4 @1 L
    1 K; y+ Y, s/ C: u5 f6 [第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    0 s5 n0 ~$ R0 S相关原理和解决方法点击详情查看。
    % e' w+ c4 [1 A
    / |1 ~) _# o. x% r% d' U1 k. S9 u第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    6 i, \5 N3 z/ w& P. c$ g& }) B/ q: f; J; ~  @  z, K
    \B) x" A: X: f  a6 W$ v+ e

    6 u: ]( M5 @& I# g* K$ Z9 m7 ~另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
    : L, ~% C; K0 m- o4 @; D
    + v, e/ Y; T* N$ ?% r% ]$ C: n3. 正则表达式实例2 [8 x# u/ |% I' A( E  J

    ' [% k; g+ w$ k4 a7 {( O' N* g* Z! E% {* s* |9 Y
    经典正则表达式实例9 S7 D3 w9 g/ |  }% o0 K$ O

    ) p! d# b& |' G8 S6 E% G匹配IP地址的正则表达式8 X( }* a0 Y# q( y4 Z1 U4 n/ O

    5 |) |1 |& }' f2 `/ [% bIP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确& w( u$ u  }* Z: {4 ^; ?0 G, S

    % c& ^8 O! _) e8 ~% m精确写法+ G6 H( t8 i9 ?( }/ P
    ' U' E0 o0 }# [# C
    0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]$ V! M3 y+ @4 U, {& S( H9 E
    (([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])- Y1 P" _; r! c1 ]3 L% L8 ]" d6 k
    原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177
    4 `# u6 d; ^& A  W% n* b5 @$ a* m; i+ s- p1 E

    * r" G" L- Z0 @: y  q8 m
    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-7-18 07:29 , Processed in 0.553535 second(s), 50 queries .

    回顶部