QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 2669|回复: 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
    : Q$ p- k: F! {( L: H
    Python爬虫 正则表达式应用详解
    # G) L; j: |9 @9 x# j% y' u7 C( E
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
    * ~6 Y; |/ ?6 p
    # d5 ~6 _* c3 `3 c7 U: B, @  e—— 正则表达式应用详解 ——
    ' v! l! ^' V! q; Y- o" e. t, \# E; e0 h" X! I* b
    文章目录
    / o/ C  L6 n: t' |$ ?
    7 \: w  r9 ^7 q5 ^! ZPython爬虫(二十一)
    ( Z% q3 `  l& `4 W—— 正则表达式应用详解 ——
    1 e6 _( x+ r, F( M% a1. 简介7 \. P0 \8 |7 Z, l5 x' l
    2. 语法
    ( B; x9 q# u2 j2 i/ U. M; ~, z3. 部分元字符应用详解
    7 S% F2 y) p: g* \^0 L# p8 X( i5 }4 z+ a2 s
    $
    1 K, S: g4 Y- f3 i* O2 o\A0 \2 X6 ]+ h* ?2 v" p9 a1 C
    \b, F+ N0 T6 b) r" S% {7 t
    \B! F; W( |6 }% j' ~  a" P7 e
    3. 正则表达式实例% H6 H& s& R& R% e  C
    相关文章:
    , q) X( u' h/ n# k1.Python的Re库应用详解(正则表达式的库)
    4 Z- e1 d* M$ I# \2.Python的Re库与正则表达式的细节解析(正则表达式的库)  ?) [4 V& M' f
    & m; b  l+ p: ?! E2 U* R
    1. 简介
    4 ~' _0 J- S3 A' y: W# X" B) W, y; P" Z1 ]& P
    正则表达式:regular expression,也称regex,简称 RE. O1 e0 V5 e) k9 ^! \

    $ b1 H: O( P7 f0 L& _3 ~, y正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。) Q. a% {0 V3 J8 C

    6 i+ x% v4 U3 R- v正则表达式是用来简洁表达一组字符串的表达式
    ( h+ D4 S% p# |/ g- f: i
    3 W& ~  L9 p: l2 i* y通用的字符串表达框架  V! v$ u! x: y) o9 c
    8 J' E* {+ S! J$ l, D
    简洁表达一组字符串的表达式7 m! _) K4 o0 k0 \, [+ c; W

    ; l, [) _5 }" {) z( o针对字符串表达“简洁”和“特征”思想的工具
    ! b7 }. x1 A0 H% }% d, i9 ~
    ; F& k+ G5 O! V判断某字符串的特征归属9 \( J* a7 V- M; ?5 I: j0 F
    4 t, n1 D6 @7 ~# r7 _' ]
    正则表达式在文本处理中十分常用
    . P* Q9 g( m, L8 W
    1 e8 ^8 [4 O4 [) S4 ]5 ^表达文本类型的特征(病毒、入侵等)8 m! q+ x3 n( b2 z$ F1 g

    # V+ ~) O" Y! `' x同时查找或替换一组字符串
    1 K5 \9 Q, Y  m6 \2 K' S: t- t! ?4 y# A- X8 f* T. ^4 V
    匹配字符串的全部或部分
      S/ N/ |; ]. @3 W/ E5 X8 o' a# d
    7 Q& ~% {4 z- w! ]+ v0 U正则表达式的使用
    / I' y, w0 `! @; J3 p0 f: a4 |7 L! J/ k
    编译:将符合正则表达式语法的字符串转换成正则式表达特征
    $ U5 l3 D& o0 q; v% O! g
    , ?" E: n* I% r4 k$ Y  c
      ^, v) K. Q- b4 h: i, X1 _) ]) L; e2. 语法( B+ D9 e: P. |. [6 W
    / w. c+ j. r" ], W! N* D
    正则表达式语法由字符和操作符构成* Y& e& ?7 e7 ^$ H8 @& U
    ' B0 ], ~$ f# O1 D: ^+ ~$ A) c
    有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。$ f2 v% a3 Y/ b' J" m3 j
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )4 c4 m0 V5 v' `% O1 H' @
    正则表达式的常用操作符' j' z+ i2 t# Y9 L: r8 }
    在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
    ) P$ l8 I  @9 H/ b  V2 n操作符        说明        实例/ N4 h' Y. |: d, p; L/ V- _2 Z
    .        表示任何单个字符(除换行符) 【注1】        0 R2 p0 _. H* q0 R4 o1 f' p3 Z# z
    [ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    6 o* m: S' b/ C2 \# L[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符- N6 s1 ?$ U; R
    *        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等% `1 N# [# S' |* h0 S# U4 X: f
    +        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
    " S- V% ]& h1 P  _: I?        前一个字符0次或1次扩展        abc?表示 ab、abc
    * i" [$ O5 _! q) q|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def- `$ O5 z) _5 r" H0 ?' t
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc% v8 Z& R' ^  o; e6 k$ e/ _& B
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc1 m+ [, T: ~/ g% h$ X; k& d& F
    ^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头2 O9 g- e8 `1 U1 {; x' n( D- H
    $        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾
    : U( s  }% h! h( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def% Q3 t% J; `: N* L: r2 A
    \        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u4 e0 q# Z4 {! H( z0 n
    \d        匹配十进制数字,等价于[0--9]       
    ! ^* Z  d* s5 w* Q" |7 z4 ?\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]        " B! F9 c% A4 o  K
    \s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
    7 s3 G2 y- ]  t, c\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
    2 }. Z$ [- P. y0 T' s- J0 p\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
    9 v! O+ f( F) K# A2 }\W        于 \w 相反        # U6 u, D6 _) a% D! y# U5 Q
    \b        匹配单词的开始或结束        ; g- x9 t& D9 D! |$ h
    \B        与 \b 相反       
    7 _, b. g* t/ O$ Z3 u# s" O\Z        只匹配字符串的结束位置。        4 G* s. Z+ {8 X/ O
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。' p# d( f: O" r# k, |
    0 a+ j$ Z$ ]1 f! l- o+ l4 m/ S
    【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    / P& R: ~, T* B* w6 H" q
    % z( W# V6 G) @9 A0 ], R- ~' {+ B【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
    * b( N; }7 d4 F) ^: b( n5 F: m4 Y2 ~6 Y3 R0 \3 c; x" n
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。; X( O: ^2 _3 H

    % i6 V8 c6 r& n& X/ g6 V【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。$ ^- m) x; n; ~
    / t) z+ T& B% h' \+ a, i6 v" I
    3. 部分元字符应用详解
    ( I* C  G% c6 H' p0 A( ^
    7 Y2 y% p) Y8 E0 S$ O# {^
    $ `% P# f; A4 e, N2 `9 p! H
    . [6 q% T: y" u& G- L0 f6 Q匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
    6 W5 X; ~5 O$ ^0 v" D
    " v+ ^  C  @; @# n- a) @+ Q: D举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:; P& [2 i$ B0 o3 K/ C9 ]% R

    ' P4 H8 h$ g! \3 h1 P9 [$ Zprint(re.search('^From', 'From Here to Eternity'))  
    : W# `8 m0 n3 K7 Aprint(re.search('^From', 'Reciting From Memory'))
    * N3 n, q( r  ?' ^  s% r8 I$ g# d15 `% v% f1 Z( C! b
    2
    8 H) M# P) H/ ?. _' O; v结果如图:
    2 x  Q! z  G! L: b$ Q- o6 R
    ' N( x' C% w4 n; L1 ^; S/ i1 \6 z1 k1 G! Q
    $
    ; {+ h. B% }7 i3 P1 W
    " @7 `9 _9 X3 t, [8 T- R# E, c匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    ) N- ?6 A0 F3 Y) _
    9 e* m1 _- Z% K( x/ Iprint(re.search('}$', '{block}'))  
    5 D5 A. |" h  h( A, D
    . l+ _: n1 e" ~& `" _print(re.search('}$', '{block} '))
    % G$ X- _4 A) A5 U/ U1 W* k* G/ W
      r6 s/ d; X7 Kprint(re.search('}$', '{block}\n'))  
    5 w0 O" X0 P! M$ z# r& `# F1
    $ b( ^- x' K" k& J$ O& f5 [21 D/ f7 L% q0 a! e7 J, y- Y
    3
    2 F! [; R: p- C7 D; i4
    3 D9 ]1 |+ i  K; n0 D52 y  h/ `$ k# _; {" ~  h; n
    结果如图:
    8 {9 t3 X8 R) p( E6 ^- R) M, o6 ^5 M

    9 n' v) A0 B5 ^9 }. L) B$ g* ~, ~/ a' |2 O8 o
    同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
    7 ^* D, ~/ Y( T' x; k, S* n, C. N% t7 g2 z1 A
    \A
    # @. C: U: X& y4 V$ A" T! M
    + S1 M( W. H8 ?# B只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。
    3 `# e  a6 ?) U# |3 \: V% X
    * ^8 Q$ N, r/ @8 a4 T0 }\b
    6 H" i  s/ q+ f+ y: v/ R) }5 e' T6 H5 Q7 a
    单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。# w  D$ A; G1 [8 A
    6 E& X3 S0 `5 `3 w0 k, l+ R7 b! M5 n
    零宽断言相关信息请点击零宽断言查看。
    + d( g' z8 A+ ~! \; {$ w$ H6 ^) Z( f( }# O. r5 y# D: t
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    3 `, D" {6 n* s5 O
    1 Z# L" c  P. [6 z$ j6 np = re.compile(r'\bclass\b'). ?. Z; z9 `; b
    print(p.search('no class at all'))  . K' I2 A& w3 `1 `

    * m+ Q" h: |4 x, c6 ?' ^. bprint(p.search('the declassified algorithm'))' t- x& f5 i, d- V5 {$ N
    & W- q  T# a5 E
    print(p.search('one subclass is'))
    7 U/ Z8 u1 x# e1 \$ u; t: `8 T1/ x; B: O/ @, E' w
    2# _  f6 l' o+ N# O
    3
    & B2 y6 m$ }% J, y% D* i4
    1 h% I: ^: I. K% p: k* b' h3 k54 g9 X$ X$ Z  }4 n$ _! F- ~6 q
    6
    & k* v8 h: }( P) l, @: W# R结果如图:$ {% G& o# g  n& e& X. z

    0 Y0 |& A: D1 ^1 {( T2 m在使用这些特殊的序列的时候,有两点是需要注意的:7 l* P5 s/ {/ m) q2 A
    9 F: I3 N5 ^; O# S
    第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    + ?( g; e6 h5 H  b: n8 p相关原理和解决方法点击详情查看。6 ^- a- ^- I6 ~

      M  v  n$ C8 \  ?! v$ Y# H% M# ~. k' c第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    % ~. A# N) x7 `  j7 Q: E: V6 d' S' |" Y8 S
    \B/ o4 |5 n& d- E+ H& k' j
    - @# j7 d+ ~9 S" R
    另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
    8 n; ?# J& ~( ^! N" {% P0 Q  L) j, c3 V+ l4 Z0 p
    3. 正则表达式实例
    , |% c6 A; J$ i+ m9 |) m# {" D
    ) @' O3 o/ R+ c' v: B" [/ k% `3 p2 r$ C4 h6 w
    经典正则表达式实例, I) p7 z) l+ w: x: }
    . |. y0 I1 x( c2 b3 m2 y9 ?, X
    匹配IP地址的正则表达式* G" m/ ~" w) {; b: D4 H1 f0 ?

    6 @: S2 X5 M- B" l' tIP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确
    * k* ]. ?& a5 a- `$ w
    ; l% I  F4 M. r; K' A# ]精确写法# E' S0 {0 e; o9 a1 F

    - P6 Q. K1 m" Q- q# Z% E, Z0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]
    ! R4 m" [9 I6 K) C- F. P: U: u2 r& v(([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]): S) ~* [) B) u( M! b  i
    原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177* z; {# I  j0 c  T( T- t
    $ T7 \3 s  L) |2 p/ i9 o2 l
    3 i& S; e5 }$ D  W( N, \0 J
    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, 2025-8-19 14:24 , Processed in 0.465402 second(s), 50 queries .

    回顶部