QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3278|回复: 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
    . K& p. c/ s) X# y* Q: |
    Python爬虫 正则表达式应用详解$ x* f) n5 Q: t6 _2 y7 r

    0 m6 V' k+ M6 ]' p6 j- R: G7 j1 x学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。4 x0 Q( J' b% a/ N' Z/ r7 }0 `- H$ L% f3 ?
    3 J- N8 U1 L' w: p/ |( j  Y+ g
    —— 正则表达式应用详解 ——
      p# U% ]8 L& i* B) T2 n* k0 q  x3 R& E& ]9 C
    文章目录+ N  c) v, a& l7 T) i1 s
    ! f* t& s. N; X" J
    Python爬虫(二十一)( R6 A6 w/ |  Q; D5 Z- c
    —— 正则表达式应用详解 ——
    ! }: \7 y7 |* A* }) v5 D8 {! S1. 简介- n( S) B5 i" |; Y! T
    2. 语法
    1 c, w( P- D' `, O3. 部分元字符应用详解" X6 R1 J; S) E
    ^9 X) e1 ?* ?2 K- q) M! R
    $
    ) @! s+ s% A+ {; y\A
    0 }" h, U- M. Q( t* O* o\b
    & y+ f: j/ A, f\B
    : g6 w0 @/ g  y4 k6 M' V3. 正则表达式实例9 A( P) N, k8 [% ^7 D/ S0 l
    相关文章:
    . j! a; t( S$ m1 ]2 ?1.Python的Re库应用详解(正则表达式的库)6 D4 S# G+ F* ?+ h, F# j4 {
    2.Python的Re库与正则表达式的细节解析(正则表达式的库)
    % M7 \- c) r- `5 _( a3 Z
    ( t  x. \  W7 H9 q: l5 i% d1. 简介
    3 z+ D" M6 S3 R, H2 p) b- U) F) O" u, m
    正则表达式:regular expression,也称regex,简称 RE% C9 a0 I& B8 ^4 E' J
    ! U! W& b$ Z5 e
    正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
    & E9 x0 O6 X: ^9 z- Z6 ?- G
    / W! h" G8 E' B3 j% C3 X: r正则表达式是用来简洁表达一组字符串的表达式) o/ k; |: R+ l

    9 `, G2 X) ?! \7 {通用的字符串表达框架2 \) p0 S6 ]9 V

    & H. c& r' J. d9 f9 u5 N简洁表达一组字符串的表达式
    : j1 D  X: }3 `3 |0 S) }/ q
    ! y/ ^7 z/ y  L! |3 _) D针对字符串表达“简洁”和“特征”思想的工具4 z' w; K" b* M7 g- c$ _
    : D# [4 L  e+ C' R9 \
    判断某字符串的特征归属" Z2 k! k9 n7 p. |% k
    ( d* O: @8 {" L( k, k- x7 l5 Z3 M) w* S
    正则表达式在文本处理中十分常用5 i2 M0 Q/ ~) a* d( m3 k& }
    $ b6 A. z* N6 @
    表达文本类型的特征(病毒、入侵等)
    % @4 ^2 @& M' F+ J; G( x* z5 ^1 M9 C7 Z+ W6 @
    同时查找或替换一组字符串* G& P8 P5 K% x. p( k5 {9 N

    ) A; x2 S* Z; I- L- e匹配字符串的全部或部分% X6 r6 V" v# `! @8 z* T. L  {
    ( {' k% c+ Q1 o  v" `8 C: w, l' V
    正则表达式的使用
    7 ^, R3 A! [1 V" b, \( i& q
    9 p7 k8 x7 t6 S5 M8 p' y编译:将符合正则表达式语法的字符串转换成正则式表达特征
    9 |# P- z1 o* S( z% M; F6 G" h$ M; {, w& l
    # N' i0 g6 \( ]" @( c7 _
    2. 语法0 @0 g$ \3 O% G

    ) M2 q) `) A; P6 z" U正则表达式语法由字符和操作符构成; q( N, W0 G/ V9 }+ l. K. Z
    - `# S  F: _* H( J
    有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。
    & v! A8 ~/ A  _. f. \+ B元字符包括:. ^ $ * + ? { } [ ] \ | ( )" ~4 D: x. a9 K7 h' O
    正则表达式的常用操作符! b$ ~. D' R4 b+ ^7 \2 O
    在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
    / {2 d9 r/ `% K操作符        说明        实例
    3 W7 k) p0 I- r.        表示任何单个字符(除换行符) 【注1】        2 \2 ]! {7 B9 V* m4 T) }
    [ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符' X. E2 i$ r9 g. `& m0 w
    [^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符  o5 M; Y; R4 A* D) y- U, x
    *        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等) B, d. H8 V" A- D# p) l
    +        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
    ! i3 Q! p/ z( a# a$ S; ~1 [4 P?        前一个字符0次或1次扩展        abc?表示 ab、abc" v2 E& N4 h/ I+ z5 r+ l- g$ t: I
    |        左右表达式任意一个 【注3】        |abc|def 表示 abc、def- G' o7 s6 o" `  |- L7 H
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc
    - W: t2 |" L  B2 I{m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc
    ! n5 l! w$ J0 y  r8 @^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头
    4 _1 W/ }" c7 a& N$ B7 \$        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾( N  r$ Y( H# r9 o( R; t( G" [
    ( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def! K" f) [2 N' e+ N8 A$ f: j  ]
    \        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u. H) t: f$ U/ z3 D4 ^4 G. c' k
    \d        匹配十进制数字,等价于[0--9]       
    5 ^3 Y7 Z- W) j\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]        6 }( p- N9 u& Y9 I. p- @. l
    \s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]        ; @' K, A4 i( _& @7 z& R! N$ D
    \S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]       
    7 K) S( t  C7 X# [! y! j\w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
    3 v6 a2 [  x0 }/ M, F# k\W        于 \w 相反        3 K& U5 @8 H- e$ o
    \b        匹配单词的开始或结束        ' v- i- g! D- |8 \! E$ v8 u4 R
    \B        与 \b 相反       
    7 b2 Y7 |2 x1 V) F\Z        只匹配字符串的结束位置。        & V( b) v* e3 N) T, I% `
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。% X, |* \& [3 l3 |; ~2 Q
    4 c6 k0 w7 ]& U' |9 D
    【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    8 }# N( W! ^& l
      h% |8 w- b2 j. z4 \7 }【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。
    7 \1 @6 {6 Y; }/ ]0 x
    ; \: b5 U; M8 S; l( Z4 m【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。+ k& Y, f! k0 ~( P# i

    2 a  W: _% N5 G3 t【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。
    + t% K  {, L' ?, i1 ~, {/ ^" G3 e2 [" G
    3. 部分元字符应用详解
    4 q7 J: T/ T, P9 A* [/ @2 N4 l. g
    ^
    - r1 S! c' H3 ^  O2 v# e' [  k
    6 r. \( ~! a! Y6 s; Q匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。
    / Q0 g) q* j" h6 x( t; {1 A. T% v) |" y# R' F4 y2 X
    举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:; f- `7 C) A7 p0 m5 B, v

    8 i4 W5 t& o& H; U' \  d( kprint(re.search('^From', 'From Here to Eternity'))  ! G6 h+ f* Z: I- S( K+ R. P2 E- E
    print(re.search('^From', 'Reciting From Memory'))
    # J) o8 a% |& d# D5 y6 ], `1( f; q* _+ h, c, n: e3 X0 H
    2* k7 w* w! w5 T. o' k5 J# ^" ]
    结果如图:
    ) v5 n0 P# B6 _7 ^  q8 ]; V9 e8 G: R. e: X1 Z& |
    3 y9 C6 `5 a. I$ ~
    $
    # l3 I4 G" Z: e% f# T" E' c1 s1 d  M3 j6 g
    匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    , V0 Z  Q; _9 l+ H% a2 K6 V  u4 D5 b$ _% Y
    print(re.search('}$', '{block}'))  
    ) S5 ~7 p; `6 j4 C
    . O% V5 b5 D! c9 u4 v& p, v: g% y" G# hprint(re.search('}$', '{block} '))/ M& x, c( U8 `, o! w4 \7 h
    ; L' R' N: B& A/ p
    print(re.search('}$', '{block}\n'))  % H  c! s- _1 @' s" U. A- ]1 N
    18 Q: x0 ], O0 N8 E: f/ o
    2
    7 @$ b' D2 q, W, K/ a3
    ( `8 z8 F5 f& r& e0 C5 A4
    + O" d8 J' A. D3 @- @2 h1 i& l/ ^50 f$ P# \1 k( }; U* `+ \. s
    结果如图:0 ^+ p  ?8 U9 v) N
      K" x- w+ o" _/ L& L/ G" ]- g. p( v; O

    2 P' H7 ^4 x7 F- m$ p6 W& a. j$ E
    / Q1 W1 [* R/ M! a' w) m" ]同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。4 X1 K9 C4 t5 k7 Y
    ! Y3 R: J% k% Q; @/ V' a9 z, p
    \A
    : r; a; O/ H+ f  z2 _: h8 K$ I" J4 Z3 y7 e( t
    只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。7 [% q/ r5 L/ ~9 V

    / b3 B3 b) m' [1 s! P\b
    8 V9 d2 u, I3 q  S) w' S
    ; W' I4 E2 L  D0 z: m单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。5 w( B/ \! q& [2 |8 R- R: |5 M

    ' ?2 u; H  U" v7 `零宽断言相关信息请点击零宽断言查看。: e9 |2 f4 [. X( q! i
    % O. n0 `3 s( p. ^1 m
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。8 t# ^$ d5 `9 {. \4 X7 u5 d3 U
    0 E  I) G1 z; o$ p
    p = re.compile(r'\bclass\b'); q, c6 R, [2 v- K6 a
    print(p.search('no class at all'))  * l7 y- K/ N4 Z- h$ z; w& }  T

    9 f! h: j$ D0 `8 G( z# p+ d1 D5 w. `print(p.search('the declassified algorithm'))
    8 G( \1 G% z: h- k" i+ m+ Q0 ^, U" }/ Q4 `4 G/ E3 c0 D6 K  X9 {
    print(p.search('one subclass is'))/ b8 n- p$ [) f7 [
    13 V1 V) C8 M. ~1 V0 J" x! B
    2
    ( C4 u3 H+ ^% b6 D4 G. W3
    . T1 C. q: X7 f4% `( E$ C  D6 u* I: O
    5( {5 @4 ^$ \& W( y  a
    6
    $ t: D$ L& C& Y* f7 ~" u" y结果如图:+ |4 `8 L+ D6 \: u1 @
    0 N$ t, g6 b8 J0 d" U; l
    在使用这些特殊的序列的时候,有两点是需要注意的:# z# P3 w% S- _# h6 Z. N" Y, R

    3 k/ u0 D4 n5 j/ [7 F第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    % ~$ D8 D9 T1 C, P) V- _! ]相关原理和解决方法点击详情查看。0 T; Z2 v1 a5 Y: k! Z3 f

    0 c5 M. r) J! Z! v2 u8 e' k5 W第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。% Z( f  V% w$ H  N# ^5 A
      C; T8 j6 {( D* G) V2 K
    \B
    6 P' x( p; U; A( n! w
    & V6 a) ]+ E+ A6 ?% S另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
    * o" l4 O- d; I* {' g9 o
    - y0 M# v2 a# X1 X! {/ n: _  _# E3. 正则表达式实例" \* }$ J9 g: a3 c) L: M0 h

    6 K( J" e, n1 T5 B
    4 W9 g" F# }$ R; Y经典正则表达式实例. o# m0 H/ B5 a( Z' G" m& ~

    ! V3 M* `: C$ m0 O/ \3 j2 W6 |匹配IP地址的正则表达式
    $ L) l- n7 `  O$ q1 X$ g# ^( {6 m3 y9 E, r1 r& w
    IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确, `, ~' W$ ^; o% G. L0 J5 N

    , s/ |7 i5 I2 d. e# c0 F' ^; c% t精确写法
    % Q( X% A$ _) J/ f0 B7 d
    6 u( y3 G' T% \5 U6 T8 ^$ `: a4 d0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]+ w9 r7 V. m  `* Y! z" 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])& |) w/ s1 r- v6 b6 y% w3 V1 }6 m
    原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177: |. C8 H" a7 `0 e8 V
    ! G. u0 B5 w" b; h- ?% L
    5 p/ m# E/ `7 |7 p& v6 h5 W
    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 22:37 , Processed in 0.393473 second(s), 51 queries .

    回顶部