QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3261|回复: 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
    , m7 r* q5 r3 N5 F* N; D
    Python爬虫 正则表达式应用详解9 U) K( u; _4 y7 C5 M9 O/ s" l, D* n
    / B: q' _; T! V' O" F/ l# n9 C" ~
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。$ r0 I0 L2 B: P6 U- d

    # o' O0 k4 b& {& T/ ~: _7 e1 P—— 正则表达式应用详解 ——; ^: u6 u; K9 X: ^& W3 j, v
    ' N6 P; Y8 \) \' C9 \) Q6 Z" ]
    文章目录
    * {. k2 [& @9 Y* V" l2 r: C1 h; h# W
    Python爬虫(二十一)! P8 q, _2 {1 |+ u
    —— 正则表达式应用详解 ——
    1 r0 d) t4 M3 ]( L+ |1. 简介
    / J$ r* N* J' d8 Y5 o: S8 v2. 语法- y" T: a# i8 x1 ^. _
    3. 部分元字符应用详解
    ! H0 @% ~/ [5 K# c6 r2 k* Z- S% U: l7 Y^1 P0 n( H- L- n
    $4 ]( b! D6 l6 A( }7 f2 L$ A2 e" Y
    \A
    ; H& ?* `5 L& [6 K\b, ]! ^/ j1 @% ~1 u" a" k
    \B( p1 Z' d# U! c3 V/ w
    3. 正则表达式实例* v  N8 f8 g" k* M  I% b% W3 ~
    相关文章:
    7 J1 ]* [6 i# q1 U. {) Z* y9 ]1.Python的Re库应用详解(正则表达式的库)
    6 R, @% n9 F. w; {$ S8 x2.Python的Re库与正则表达式的细节解析(正则表达式的库). m$ U. t- |/ d; y9 B. k* D

    , X" }% w: Q9 j- J0 z4 I1. 简介
    / A: U* Z6 f- {! e/ J# S5 Y+ n- Y& g! M$ ?" `
    正则表达式:regular expression,也称regex,简称 RE) j% B- m5 b; f. `1 m; e1 ^
    1 ]7 R! [4 r2 R4 e" G
    正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。
    " e9 ]' ~& s1 E) s, v) c( i
    : g" S8 ~5 b% h/ _) n- Z. L# H正则表达式是用来简洁表达一组字符串的表达式* L4 j  ~# R' p
    * K* t* c/ g2 f7 @' z* Z# l9 C$ d
    通用的字符串表达框架) d! v% H: A, ^' j  `

    ( l# _* l) Z7 J' n. N简洁表达一组字符串的表达式
    7 ]' w: T/ W5 Q5 X+ i8 T: a, p8 [: E4 B
    针对字符串表达“简洁”和“特征”思想的工具$ B8 G/ C2 H) C5 g, `

    ( J" ?5 r, b' S+ Z( s判断某字符串的特征归属
    2 s& B8 p$ n* n6 P6 u! f* ^$ w; ^- }/ A, b
    正则表达式在文本处理中十分常用' i6 N  \% o8 B& L

    + y; s$ T0 _2 ]( _( ?- G表达文本类型的特征(病毒、入侵等)3 U! u& s! M9 M2 j' @/ i
    % }' Q2 C' ?1 m9 d
    同时查找或替换一组字符串5 _2 J% L( B% T- r3 N' C

    - j1 B9 H% J; d" ^; j" {" ~匹配字符串的全部或部分
    / r( a# O1 V/ L- \/ z! N& N9 x3 ~( }3 K% _: {! U
    正则表达式的使用
    - a/ w" M- V5 K2 G8 I* e9 c$ i4 S% R; c0 N/ N  Q
    编译:将符合正则表达式语法的字符串转换成正则式表达特征' G/ M8 W" R( z2 ~9 u; q" p* f

    0 [" q# O/ A" e# O) ~+ i! ]( l2 }3 W, J1 N$ ~$ m0 o" ^, s4 B
    2. 语法
    ; D8 Y2 N$ {% }6 @1 P" q) U6 G, o
    正则表达式语法由字符和操作符构成
    3 L! N. r# Q+ h& Z9 H/ ]& X
    ! Q5 y6 W6 l0 {7 A. g有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。8 Q' f7 }/ [  [  l, P0 a
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )8 ~) d! K# o7 u! Z2 Z% @9 m* n
    正则表达式的常用操作符0 U" J/ r/ c% I, f  r& L
    在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发
    . G8 H1 ~7 n3 M. G0 c" E操作符        说明        实例* @# k  H/ o1 s; e" J/ y
    .        表示任何单个字符(除换行符) 【注1】       
    0 \: J, G" b- I6 I. Y' k[ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符, Y1 u7 V  q6 Z: f! C' s
    [^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符
    % O- ?/ Y6 Z  R  v; c! j*        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等
    8 g! b7 V0 X% U2 F' ~8 S+        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
    0 `$ C+ `) \% x5 M, o: K?        前一个字符0次或1次扩展        abc?表示 ab、abc
    & |5 c  ~. ?" Y( O4 x, i( X" E4 }|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def
    & \" S9 y7 k& e; m( Y8 t{m}        扩展前一个字符m次        ab{2}c 表示 abbc9 p, F3 {  r' b- ~1 f
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc. C0 G9 E6 r! l- u7 x! L7 c
    ^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头
    & H  l1 @) B; a$        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾
    - S* s  O2 v0 z) t( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def
    5 n) f2 w5 [4 D) n$ b\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u
    4 J( y4 b* h! N, Z2 L/ K, `\d        匹配十进制数字,等价于[0--9]       
    4 ~9 _* c1 ?) i& @\D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]       
    0 V3 Y2 O( i: c$ t" Q, e6 X\s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]        " g% A' n) B: F; ^& r
    \S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]        5 x" Z8 f& R2 `+ V4 b% R
    \w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]        ; S; @: I/ h8 }2 K
    \W        于 \w 相反       
    # x, t& f& ^; I- [' r, Q\b        匹配单词的开始或结束        1 O! C9 t7 H, b3 d
    \B        与 \b 相反       
    5 y& e: e0 w5 j7 X8 ]6 h\Z        只匹配字符串的结束位置。       
    0 J4 j- u* f% e! R* E' F【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。: V$ V" V2 e% M. ]' G% S

    9 n) [& _2 s- i" ^3 w【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;8 S0 N- j5 {2 c( T/ ~% s
    8 A! w; J( X/ h' l) j  f
    【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。- l1 ^5 G1 @6 j
    6 u8 @; f' o$ X5 j
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。
    ; Y. t& v  a6 b  F  V1 p& c; a9 u  ^9 j
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。
    - V, A9 y9 K# g4 Y* w; F% m$ C+ U6 O/ `, u8 w& d$ O" Q4 ^9 m
    3. 部分元字符应用详解
    9 l+ s9 k0 W' b/ Y' D
    1 ?, O$ U, V( ~^
      ~) O1 }6 ^( T( m7 w# n$ E/ M$ [5 M  x+ T2 C
    匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。% Z- e0 @' g) U! L5 e/ f9 U
    , A/ d* n( W8 ]' m' Y
    举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:- l9 e/ a  N2 ?
    7 [' y& ?8 \$ P! v- |
    print(re.search('^From', 'From Here to Eternity'))  
    ( [1 B% f1 ^5 G- }3 vprint(re.search('^From', 'Reciting From Memory')): O  [0 S0 L) j
    1
    . f! d" }: v6 e0 H+ C" E25 ~% ^; l$ N0 {  g$ Q* n2 S! g/ d
    结果如图:; @, Z& m) w7 S' Z# ]5 l) Z' O6 h0 D
    7 x$ y9 o# t$ v8 \. A

    ! a* c* a2 @) _, y$; C: M: r" Q) F$ K$ c& k

    # x. m( f9 H- x' M$ N匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。  v# U" S3 l- ]( [5 l) `

    7 e. Z! w- _1 g0 O' C- {/ Z4 Qprint(re.search('}$', '{block}'))    p" x1 B' h0 f! b+ B/ K/ E  Q0 y

    ; R% P- n, j' o5 pprint(re.search('}$', '{block} ')). _+ c- \: f8 p. o$ A8 U
    % Z. R8 l& S; G
    print(re.search('}$', '{block}\n'))  / v" u; l% k0 S" ?  T% _; ^
    1
    5 K# l. @0 W4 ?" w$ W* y2
    # Q+ j6 I9 _2 c# ~2 s  q- J37 N' F/ O4 t. A$ F" Q
    4
    5 W0 s' ^  I( _2 u3 m$ _; u/ W5
    # h( F9 a3 H, \* }/ S( E6 R* ~结果如图:
    3 W8 l2 w$ b% I2 W; [) v
    ! \! ]" V+ F2 o: ]! H( V9 b- I4 x- X
    9 e% i8 g; s0 P% [; G* c9 S
    - t8 R. N( y- ]* u( X2 T同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。
    ( x- u3 U' r* O# x5 |! R) U" l5 \" U2 B5 d2 T" i) d5 c
    \A/ C2 w. c1 `0 n- E* j
    6 K: d* Q# \& f( h  V1 i
    只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。- B5 C  X& j9 `' V
    % ]7 y$ L4 s! H( r1 U/ A6 _
    \b
    5 G$ J4 H6 P0 l" H9 b
    $ G9 N: [& h/ q5 X单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
    , w7 N& z/ J0 s3 I' ^
    & ]  T: z% X, M! C- {零宽断言相关信息请点击零宽断言查看。
    ' ?! l4 I8 h& N: |9 C4 i3 ~$ x$ g+ B9 ]: Z& m. |8 C3 d
    下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。& O  c, t/ O: q" g+ C2 L- i3 K

    ( A/ k& }  L/ \* o1 Np = re.compile(r'\bclass\b')
    8 l! O1 \* J: u# @% z0 o( F$ qprint(p.search('no class at all'))  
    " M& v# I; t6 I) J
    ' _1 B# O# q/ o8 @5 q' @print(p.search('the declassified algorithm'))2 L( T3 I( z" _% D+ l, U
    ) t1 G  B2 P( X! ?2 t5 V
    print(p.search('one subclass is'))
    2 j/ w' P- T) T: y: W" [12 o1 U6 z- f' ]
    2
    ) p& W( X# c, `, g+ a: y: T3* v" q( X4 G* F) }1 W- {' i* S
    4
    ; R, V+ Z" w$ }) a0 q5
    0 Q9 C9 a7 ?5 K  Y4 T6
    % S% B0 G) B+ a4 m结果如图:% g( J% Y, ]; P# h) m! h

    & t3 \: }9 M: j/ b" E3 X5 x' K' e在使用这些特殊的序列的时候,有两点是需要注意的:
    : R& V; q: Z' n/ j! e; D7 Z6 M% C. @. F9 O0 y! I4 E
    第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。
    2 T* z$ Q4 T9 X# {. Q* N; n# d相关原理和解决方法点击详情查看。
    # _' V4 E5 ?1 m1 }2 _. C# p
    8 V; E% `& u; d- W第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。9 ]- B7 [2 a% ]+ o2 W

    9 W3 k7 n0 V- n5 f\B
    " N# {1 B( P. |0 }
    : Q- a0 m8 D/ n% K3 u另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
    4 y9 ]; S; t! a
    1 k) r' {7 Z0 v' Q, v3. 正则表达式实例" Z+ p1 e' |3 B& v

    # C# U9 I5 L; p0 W" U) U, k' l$ H% w! m6 D, z
    经典正则表达式实例
    0 X& f  X; ]& n+ C1 n+ d  a, w7 Q5 e) L0 v* y3 K. z
    匹配IP地址的正则表达式* U% I, d& C1 k; ~) S

    3 Q% x& s* Q2 FIP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确
    ; y! A& L; C0 j6 N8 ]7 \5 O3 r! V) b. h0 f5 C
    精确写法
    ) G/ ^/ I/ R1 J6 G3 l# h8 F+ F5 g
    0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]
    0 @5 T, o% z- O( l3 C& E( M(([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])
    : `5 c5 `/ n  e% f6 k原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177
    ) C. W. y7 E! M6 q
    / H! M$ e0 R3 J: ~4 [* _  ~% C4 F7 j$ x3 w7 F
    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-4-21 09:35 , Processed in 0.352388 second(s), 51 queries .

    回顶部