QQ登录

只需要一步,快速开始

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

    ) h! w. b' G* n2 J* p1 ]1 E' dPython爬虫 正则表达式应用详解
    4 `  P6 z2 K: n4 v/ H5 {1 L8 Q, A2 f, P: T
    学习Python爬虫过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。
    . L% ?! d2 Z" C9 C4 Z& u4 A, I! a/ L. Z
    —— 正则表达式应用详解 ——
    : Z) T" c' m7 q! r, o9 w1 d4 ~4 f' V4 r% k) y1 E
    文章目录4 p2 ^4 K2 b5 S3 R3 a
    7 E2 ?: F( s; W2 ]
    Python爬虫(二十一)* T) Y  \; _$ K9 o" _# A
    —— 正则表达式应用详解 ——
    % z" ~$ r. u+ u$ T# a  f) v$ a) x1. 简介+ F& ~& e) m- p  w
    2. 语法
    0 U8 g/ z" ^$ F+ [& I9 l' {3. 部分元字符应用详解
    % k1 p9 n/ W" u. \+ J0 m2 M^
    : w9 H- f/ \- b3 I- x+ T$ ~- f* `$
    $ z7 m% c! _. @- i* p\A- I9 a, L' M8 w* s% L& y& C  i
    \b- v7 I9 }3 O/ T8 |
    \B6 A, B) S- ^  l# g) a% s8 s1 R
    3. 正则表达式实例
    5 Z0 n) ]# y& Y+ r& Y相关文章:) G! ?7 a' L" o* y. s% F; i) D6 S% ?
    1.Python的Re库应用详解(正则表达式的库)
    3 p5 ?1 m6 O8 f) K) p7 t/ h- J* ^2.Python的Re库与正则表达式的细节解析(正则表达式的库)% ?& N& p2 w& k/ K+ \- }: [

    ( b8 p! O( M2 j( M( Y* j4 t# j1. 简介9 F* _. I7 e: O) D
    ! S# l6 l4 S% n! S( u; u. ~; x& M
    正则表达式:regular expression,也称regex,简称 RE  y( k9 l4 j" F; s

    7 d8 O$ `" V; g8 m% M+ X9 |4 K正则表达式模式被编译成一系列的字节码,然后由一个 C 语言写的匹配引擎所执行。; [# W  b, G5 x. W; l. L) @

    % i! w4 A1 c+ o: I! D8 k正则表达式是用来简洁表达一组字符串的表达式
    % w; S" U9 k# b: c1 u5 @4 l' F! S: b0 D
    通用的字符串表达框架  o6 j$ o7 l) k% [* y. I

    ' ~. I- e  }' K1 g3 `% ^) f+ l8 P简洁表达一组字符串的表达式
    # [8 _1 F; w+ H% N5 t- Z3 W: k& v
    : x0 |$ b3 E  [1 J) `针对字符串表达“简洁”和“特征”思想的工具) g) R" W0 x, i3 M$ ~5 {
    " v# y0 W7 ^7 p0 |5 {) V. Y4 P
    判断某字符串的特征归属0 h. S% a0 N0 I. K/ n" x

    ; g  N& O$ B/ x  W/ k正则表达式在文本处理中十分常用
    1 Y" g% s6 S7 f; k/ D3 C0 x
    6 D. Z. p. h5 J表达文本类型的特征(病毒、入侵等)1 h" x3 `4 p% |7 ]8 k+ U
    : W, L8 o* j) b' N! k, Z
    同时查找或替换一组字符串& d3 f7 T* ^; O& n! A

    , y$ I! G1 E1 w4 G9 m5 a4 v匹配字符串的全部或部分
    4 t/ e) h9 Y- Q1 q& E6 u; _3 |
      X4 G* q2 z# @* K/ L正则表达式的使用" w  Z2 ^  `' X& v& X+ L
    / j2 `' H0 A  Z4 o& O
    编译:将符合正则表达式语法的字符串转换成正则式表达特征
    1 z5 Y/ V  z1 H8 F
    5 b- Z, L4 o- Z' T! c* h; B
    ) v' t3 r. B5 |3 L3 H2. 语法
    " k* S1 w& {8 ]2 P
    ' n( z$ P$ S8 [正则表达式语法由字符和操作符构成+ Z* u. E) E- V) A5 C
    8 ]. p4 ~4 D$ ^0 W
    有一些符号不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等功能,被称为元字符 (metacharacter)。' x. R% R# B, t
    元字符包括:. ^ $ * + ? { } [ ] \ | ( )% u1 N# \6 E$ @& }" L8 h( V
    正则表达式的常用操作符4 m/ |" A" c& ?1 x# f# k* G2 s
    在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发% J' N& n5 }+ y* G; v( {  ]8 `
    操作符        说明        实例: ^% g; Z% A2 Y, w9 l' C$ I
    .        表示任何单个字符(除换行符) 【注1】        5 G2 Z( W1 a( _" D' z
    [ ]        字符集,对单个字符给出取值范围,元字符在方括号中不会触发功能        [abc$]表示a、b、c、$,[a--z]表示a到z单个字符
    + N6 P5 Y( ~6 ?7 y' [; p[^ ]        非字符集,对单个字符给出排除范围        [^abc]表示非a或b或c的单个字符
    , t: }+ p1 z/ f% h* L. @*        前一个字符0次或无限次扩展 【注2】        abc* 表示 ab、abc、abcc、abccc等
    ; u' s' A% ^& t& h+        前一个字符1次或无限次扩展        abc+ 表示 abc、abcc、abccc等
    5 ]) ]: s0 Q) n) _: _% _; ]& o/ k?        前一个字符0次或1次扩展        abc?表示 ab、abc
    . X, i  C7 x" z) X) E4 E# Z$ z|        左右表达式任意一个 【注3】        |abc|def 表示 abc、def0 W; c5 c$ O# ?3 E: |
    {m}        扩展前一个字符m次        ab{2}c 表示 abbc0 z0 M; k9 t3 t9 U7 Y# Y
    {m,n}        扩展前一个字符m至n次(含n) 【注4】        ab{1,2}c 表示 abc、abbc  \) x* v; z; K" o  ~3 O+ ?
    ^        匹配字符串开头        ^abc 表示abc且在一个字符串的开头
    5 O' H0 }% r0 J& H$        匹配字符串结尾        abc$ 表示abc且在一个字符串的结尾) `0 H3 S0 |5 `, x+ O% I# @- ?. i
    ( )        分组标记,内部只能使用 | 操作符        (abc) 表示abc,(abc|def) 表示 abc、def
    ; }$ t0 {0 Z+ D) p\        后边跟元字符去除特殊功能,跟普通字符实现特殊功能,如需消除反斜杠的特殊功能只需在前面再加一个反斜杠\\        \d \w \u: l% _$ [) E. c$ \+ E4 y$ `( E
    \d        匹配十进制数字,等价于[0--9]        ; v4 F  J+ w+ {5 X
    \D        与 \d 相反,匹配非十进制数字的字符,相当于 [^0-9]        . V  g. b8 R/ ~. a" |) t+ ]; [
    \s        匹配空白字符(包含空格、换行符、制表符等),等价于 [ \t\n\r\f\v]       
      g# A( U% u, {0 u8 T3 E& F\S        与 \s 相反,匹配非空白字符,等价于 [^ \t\n\r\f\v]          `2 t0 o# O' \" I
    \w        单词字符 【注5】 ,等价于[A--Z,a--z,0--9]       
    ! R1 L3 b4 G$ O\W        于 \w 相反       
    " F/ b5 j( P$ Z3 c* F( n/ g& |\b        匹配单词的开始或结束        / }2 g& G& u5 G. a: L' o
    \B        与 \b 相反        ; f# N  C/ h3 N$ l- t
    \Z        只匹配字符串的结束位置。        ( C, {' Z! f; v0 f
    【注1】:如果设置了 re.DOTALL 标志,. 将匹配包括换行符在内的任何字符。
    3 g, }/ z! d  ]" G* u% B5 j2 R# [
    2 j* p5 M' G9 k4 c6 ]  d& I【注2】:由于受到 C 语言的 int 类型大小的内部限制,正则表达式引擎会限制字符重复个数不超过 20 亿个;
    2 W; M2 }* N" Q- r
    # r+ {8 [5 {! A. `【注3】:为了能够更加合理的工作,| 的优先级非常低。例如 banana|orange 应该匹配banana 或 orange,而不是匹配 banan,然后一个 ‘a’ 或 ‘o’。同样,我们使用 \| 来匹配 |字符本身;或者包含在一个字符类中,像这样 [|]。+ H! A& }) H4 P& ~0 y' O
    * P6 R4 i* v6 i; l- h# ~
    【注4】:可以省略 m 或者 n,引擎会假定一个合理的值代替。省略 m,将被解释为下限 0;省略 n 则会被解释为无穷大(事实上是上边我们提到的 20 亿)。" D  V! U( s& p3 k$ A3 G2 w
    ) R7 w7 y" D5 v1 M3 M7 U
    【注5】:\w 匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符类 [a-zA-Z0-9_];如果正则表达式是一个字符串,\w 会匹配所有 Unicode 数据库(unicodedata 模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供 re.ASCII 表示进一步限制 \w 的定义。
    + v, a# Z- V2 }/ n& b4 K/ Y
    : G! b( E6 z/ _, G! s3 G3. 部分元字符应用详解, J( U  x- ^" W3 E9 Z
    1 A" ^" n6 j! \+ s" D
    ^
    $ }5 i) `  d) }# I# d5 k2 g* l3 |
    7 d" O) j9 \1 C( ]匹配字符串的起始位置。如果设置了 MULTILINE 标志,就会变成匹配每一行的起始位置。在 MULTILINE 中,每当遇到换行符就会立刻进行匹配。" Q' G& ^5 @, ]3 P0 |+ h

    * m% ?' V0 x3 E' r4 |举个例子,如果你只希望匹配位于字符串开头的单词 From,那么你的正则表达式可以写为 ^From:8 |, w% U+ R- W) l' V# r! P
    , F) D, I. x( M/ P& k
    print(re.search('^From', 'From Here to Eternity'))  
    / ]+ }" n# D+ D) `print(re.search('^From', 'Reciting From Memory'))& `. M$ ^, W9 `0 k! A
    1% A9 o( J3 K, M$ u8 S
    2  Q  E- j+ \1 y9 T
    结果如图:9 ]- e- K$ c: I- q7 c2 e

    ' V! w2 m! \* X5 s2 h% k5 Y' l) S) l, f4 J8 U
    $) C3 W* u% Y2 F+ W/ d
    6 y/ U6 |9 N2 T
    匹配字符串的结束位置,每当遇到换行符也会离开进行匹配。
    6 G& X' j2 e9 B% ^" _1 h
    # {4 U% O* {. L' x# y. C* Oprint(re.search('}$', '{block}'))  0 E6 ~! B. v) |" P  K' o! I( s) k  n
    $ ]8 {9 C1 E4 ?* z* d" x0 Q
    print(re.search('}$', '{block} ')). B$ O) ^% B  q5 v& @

    $ l) P: x2 n2 ?& v4 \$ {print(re.search('}$', '{block}\n'))  # w8 F0 _* H" @  L  P% [5 c- Y
    1: l) `" i% d5 n% p  E
    2
    - u/ t9 u9 k# c8 Q7 r  e: E. M3
    3 J  B9 b- J, l4& m0 X- G; B$ q( l( t' @7 W3 R4 ?
    5% q$ `2 D9 U: V/ e7 d1 N- \+ W* p; |
    结果如图:9 b5 @7 N) x- a$ n% s, k' i
    3 {2 z+ q- ^# `
    3 }2 a1 H( J6 }- h" J
    ; |: x' y3 ?8 _  U3 |+ W  t% g6 |6 A" F
    同样,我们使用 $ 来匹配 $字符本身;或者包含在一个字符类中,像这样 [$]。0 I; ?0 C- a/ b

    + q2 \6 u6 _+ g% z; b- x\A
    + R  p. p" p. E( ]2 f* Z8 z. I+ h8 u2 S$ p1 w
    只匹配字符串的起始位置。如果没有设置 MULTILINE 标志的时候,\A 和 ^ 的功能是一样的;但如果设置了 MULTILINE 标志,则会有一些不同:\A 还是匹配字符串的起始位置,但 ^ 会对字符串中的每一行都进行匹配。
    7 I5 l3 Z3 b, N- S
    6 V$ l# q. b( a+ W6 W) B5 g- r( b\b
    4 N+ v# I, k6 X1 u1 l  _1 i" L8 n1 ]2 {
    单词边界,这是一个只匹配单词的开始和结尾的零宽断言。“单词”定义为一个字母数字的序列,所以单词的结束指的是空格或者非字母数字的字符。
    " L  e) C. _/ ^( f, G& _' D$ {! X+ S" `: U, w; m
    零宽断言相关信息请点击零宽断言查看。
    # L# \5 E- ?! @, a0 E
    2 S) h0 E) p4 n3 w3 V' P下边例子中,class 只有在出现一个完整的单词 class 时才匹配;如果出现在别的单词中,并不会匹配。
    . U9 I* [! ~! i) |2 }8 D  T; }7 W. i; s4 N
    p = re.compile(r'\bclass\b')
    * i, u7 s$ C: S2 ?" ?' _print(p.search('no class at all'))  
    ( ]9 Q( R3 g% e- H6 T, n5 W* ^( g9 e) y3 E; Z* R! |( r
    print(p.search('the declassified algorithm'))
    " ~4 B4 s1 n) v' r0 n0 a
    1 o  p4 g5 u* Y# Xprint(p.search('one subclass is'))5 H% {0 j6 x. @& F3 P9 A
    11 b+ U$ u2 w$ L0 J
    2
    4 y1 ~0 \) f! N3
    $ |3 M, O8 p. W4( A/ U( a7 s* q0 x( s+ a
    5# Z+ B3 A+ x4 z& v; y0 c' V
    6
    3 s4 Y3 K$ p. o! F  W  \( U结果如图:8 p$ @2 a3 ~- ]- t  p  F
    * i7 O) B: u9 @! k
    在使用这些特殊的序列的时候,有两点是需要注意的:
    ( Y: ~/ O) L3 w& O! x9 q# E8 e) z& }) @+ f$ Y
    第一点是,Python 的字符串跟正则表达式在有些字符上是有冲突的。比如说在 Python 中,\b 表示的是退格符(ASCII 码值是 8)。所以,你如果不使用原始字符串,Python 会将 \b 转换成退格符处理,这样就肯定跟你的预期不一样了。# r, b) @9 j) W
    相关原理和解决方法点击详情查看。- ^  I; h% c; w6 O; I
    & P9 I% W) F; H/ f
    第二点需要注意的是,在字符类中不能使用这个断言。跟 Python 一样,在字符类中,\b 只是用来表示退格符。
    " D* t% H: B' i# v* y) o- }/ g/ X( F
    \B
    * {$ T0 _1 p7 |3 S1 h( B* u1 O- O9 }  b. Y
    另一个零宽断言,与 \b 的含义相反,\B 表示非单词边界的位置。
    : U, \) b, N$ \  L, ?8 b. h/ _) ~& o* ~) t" V' w" W" n
    3. 正则表达式实例: S7 R1 _5 I. q; s0 G7 h% _

    8 Y% L/ y, ]4 L
    : ?# s, z% y" W3 ^- V经典正则表达式实例
      n( Y6 o9 A& ]( i& Z! ^% i& D' b7 a- V+ p: ~
    匹配IP地址的正则表达式
    ' {! `4 s$ w7 d  i' w5 u7 K8 F3 `4 I* X6 ]  Q" c
    IP地址字符串形式的正则表达式(IP地址分分4段,每段0-255) \d+.\d+.\d+.\d+ \d{1,3}.\d{1,3}.\d{1,3}.\d{1,3} 不精确9 L; k7 F$ R' }& T) v+ V( v
    ( E/ s9 D0 T' K: U0 M3 y% ?- n
    精确写法
    / s4 z. ?" {- k( A3 Y
    , M% O3 M6 [0 S: |1 w, Y0--99: [1--9]?\d 100--199: 1\d{2} 200--249: 2[0--4]\d 250--255: 25[0--5]" M* E1 G/ h! X' ]
    (([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 @* R+ w6 }, G2 P. [/ d3 C5 j* `原文链接:https://blog.csdn.net/qq_44867435/article/details/105104177( ?3 R5 U1 A( L, ~

    . j6 b* b1 K+ P4 J; _
    & s- c0 M0 S) N, N9 b  @& e, ^
    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-3 11:12 , Processed in 0.438330 second(s), 51 queries .

    回顶部