QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 1955|回复: 0
打印 上一主题 下一主题

Python正则表达式(一看就懂)

[复制链接]
字体大小: 正常 放大
杨利霞        

5273

主题

82

听众

17万

积分

  • TA的每日心情
    开心
    2021-8-11 17:59
  • 签到天数: 17 天

    [LV.4]偶尔看看III

    网络挑战赛参赛者

    网络挑战赛参赛者

    自我介绍
    本人女,毕业于内蒙古科技大学,担任文职专业,毕业专业英语。

    群组2018美赛大象算法课程

    群组2018美赛护航培训课程

    群组2019年 数学中国站长建

    群组2019年数据分析师课程

    群组2018年大象老师国赛优

    跳转到指定楼层
    1#
    发表于 2022-9-7 15:37 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
    Python正则表达式(一看就懂)# l2 Q: j$ @0 r% x4 E
    2 U7 p  L5 j6 L
    目录
    5 w; f/ X, S7 w. W0 k
    , m' N/ Q* ^, X% l) Q哈喽O(∩_∩)O😄
    ) C9 J. k! p( m$ j' u1 r
    % `# ?, ?. m# x2 M什么是正则表达式(⊙_⊙)
    9 O$ f3 d0 O0 s, y9 K1 x* w' `+ \  @+ _. I3 E7 c9 u% m$ V
    简单说,正则表达式是…' H! E/ l* |+ @1 q3 D: M0 S2 ~
    3 I" P, M. U) d
    正则表达式怎么用❓
    4 y7 h. L9 Y% i  M
    0 S; b! r( E  y: M/ ]0 M& nsreach的用法🍊
    : i, Q' t% R5 g! t+ b) x7 w2 b
    & m4 M8 {" F+ z匹配连续的多个数值🍉1 u) {; b7 o$ D3 o9 E
    2 a- z6 _2 E) i# H2 {
    字符"+"重复前面一个匹配字符一次或者多次🍉
    $ I5 u' ^( w  \9 S# K
    " v4 Y$ G# L- r字符"*"重复前面一个匹配字符零次或者多次🍉
    ' x3 j) w( d; t. q: O
    8 E  q6 r, l7 K, `" f2 W  k字符"?"重复前面一个匹配字符零次或者一次🍉! ?6 X) i9 V2 J  R* X( H" t/ ?

    8 N# v7 {% F! e0 o( ?特殊字符使用反斜杠"“引导,例如”\r"、"\n"、"\t"、"\"分别表示回车、换行、制表符号与反斜线自己本身+ P1 g4 ~6 d! Q  D
    % D. R1 Z' |3 ?( Q
    ( l8 S  {& Y2 h
    5 v  {/ v2 w- R1 \1 t
    完整表🔍
    7 Q' B$ M  C+ s+ e7 R: [& n( V% |- }& X& O7 c1 i  y
    match用法🤔
      s, C2 O: F7 Q2 k1 f2 ?( |* ], U; ]
    match用法😃
    & v2 g: f1 M1 o  r  G* Q7 D$ ], y/ B2 g! \8 j, I7 L- I
    match对象🍊
    * E- O* n' |4 F* J1 p1 K% z( {- d6 N% P: `  N: m/ l# y. J, T0 F8 \
    数量词🍊
      U$ b, h* d4 Z/ m+ I! ~
    . J/ q& ~( X! S; I5 I% v匹配开头、结尾🍊
      ^) Y" H) `1 V& C5 y( }$ y$ b$ p" W4 h& K8 v
    0 a( S4 G2 v0 b' h& \- w" }0 B

    1 }$ G5 R: X" T8 N0 a- _: v. y( t  l 匹配分组🔍. |  O* c) F% f9 Y8 f4 B
    - t2 ~  F( ^5 [( C& P
    match总结😄2 H5 @' ^  z$ k" [0 o- G' U' N
    0 F+ ?9 b2 ~! O: }. [8 k* [
    实践出真知 凸(`0′)凸 ☀️8 A9 i. Q6 i, M% M, O0 G
    ! S  x3 s; J% J& b3 d- H
    写在最后🧐, L- {: _5 Y" b; v2 g9 a
    - a4 k4 E1 B& H* ]0 y
    哈喽O(∩_∩)O😄- c; P3 x) L* _
    今天来发一下python正则表达式,其实这个也是比较简单的7 h3 Y  @1 b) ]" m

    # ]: r1 t8 }1 ?, L- m肝了好几个小时才写出来呀+ ?. d1 c# I2 j8 Z( R) [
    " J1 E4 k. y8 A: E# V- F  J
    什么是正则表达式(⊙_⊙)
    * }* O3 w, B( h0 @目前越来越多的网站、编辑器、编程语言都已支持一种叫“正则表达式”的字符串查找“公式”,有过编程经验的同学都应该了解正则表达式(Regular Expression 简写regex)是什么东西,它是一种字符串匹配的模式(pattern),更像是一种逻辑公式。
    4 t: ^% ?6 F, z2 p) t
    " l9 I9 }- C8 D3 E1 z简单说,正则表达式是…
    6 l, E7 y% K. R* c' Apython中必备的工具,主要是用来查找和匹配字符串的。; G# t1 D4 m: F. ~8 z( R
    & Q9 y5 ?( w  a4 ^! O0 C$ p3 _
    正则表达式尤其在python爬虫上用的多。
    % A$ `1 e+ b2 [, ]& u# I" u1 z- t! {/ H3 @, a2 J
    正则表达式怎么用❓
    1 o' H: o& u8 E# ?* t: X首先,我们要导入头文件(写c++写习惯了)模块0 |* H# l' [% f
    & Z$ U& [! A7 I3 b" a7 e
    import re8 P0 m; R( M5 Z) e8 S4 F0 u8 v( E/ l
    因为re是内置模块,所以不需要额外安装,就很银杏/ K  ^. }: h! B/ J
    & W2 ?. ]- N' x: d! H; X* l/ f* E
    sreach的用法🍊
      A$ H  Z9 @4 c6 W: w% u匹配连续的多个数值🍉1 S( {( m, ^) I
    - j6 w+ g8 b( f, r. s8 n

    6 W7 M9 @) C% ^" r3 F+ [import re
    + W9 R/ l4 \# C: ~6 z/ f. r) r* H7 y  t/ Z$ H  P
    r=r"\d+"4 S4 y) j, a3 x+ i) n
    m=re.search(r,"YRYR567eruwgf")#目标是567
    ! j; r2 |, ^( V# B4 X1 Eprint(m)$ q" |! x' k2 W# z0 `$ \, j
    1 Z! `* A* F+ E" F
    re模块中,r“\d+”正则表达式表示匹配连续的多个数值,search是re中的函数,从"YRYR567eruwgf"字符串中搜索连续的数值,得到"567"
    0 V  l+ J) {3 v- v- h$ I* v3 W2 }' a7 M. E% D
    结果:
    ( R& G( Q9 J5 h1 U" [) T" V+ ^; t& i
    2 F! t) K; X4 c4 ?* l* G; ^
    ! U9 N  v5 m% q2 j1 v4 E8 @
    可以看到,搜索到了连续值“567”" I8 s9 ^0 K( a5 H; N
    9 X7 L, p9 M/ a3 D  K
    字符"+"重复前面一个匹配字符一次或者多次🍉6 A+ m/ W) n1 x- L$ ^- C! a0 Y

    # B" ^1 L) i* D$ A
    " b7 e) O, M0 X% rimport re
    3 T) W( w, v! \, T& C3 Q7 j
    , N# d3 E* N: S9 J) R1 `: R2 Nr=r"b\d+"4 A! l- x8 F6 q( y% E
    m=re.search(r,"a12b1233cd")8 g0 \% h+ v7 i8 d; X0 m" J  q" z
    print(m)
    ' Y: [, a/ Z! ?. E/ ]" L
    8 Y" ~+ |' b; R0 R0 ] 这样,结果就是b后面的连续数字; X& }) H6 _9 Z- P

    . w8 P. X& b8 S3 D2 L9 K2 \  z5 G结果:" J- A/ p! c- M$ z+ T3 G+ P7 Y, j
      \6 `% N; d. `& {4 w0 S

    , d) J% Q# I0 K3 U2 d9 K4 B6 F3 z
    5 B/ e! B1 m$ t9 R2 O8 F字符"*"重复前面一个匹配字符零次或者多次🍉
    # d& _, [. S& [" _# k6 ^* p“*" 与 "+"类似,但有区别,列如:
    % A& L( K- Y% o# W  C& o可见 r"ab+“匹配的是"ab”,但是r"ab “匹配的是"a”,因为表示"b"可以重复零次,但是”+“却要求"b"重复一次以上
    " c  w# r7 _( g# t, S
    7 O2 V7 D; A0 H# E4 B; }0 c0 |' M$ X% P1 X  o3 h$ h! \& V

    ' [$ h' v+ R  M' g1 x! d/ u  h4 Eimport re2 Q1 J" C! H0 e6 P! S" _, g
    , B9 e" R( E; V, g; N/ i
    r=r"ab+". r# M9 W4 o; C% c, G; i( W$ `
    m=re.search(r,"acabc")
    1 m1 q5 Q/ g% ?0 L5 {* s2 rprint(m)
    & m% W1 c3 C5 ?* y, ], }/ p5 c1 @( e1 \5 X4 t+ B
    r=r"ab*"; d* L% I! O5 o9 n" Q5 y: n7 A
    m=re.search(r,"acabc")
    : Y* R( P7 I, ^. q; z/ }' }0 t# }print(m)! v; A6 i* {% F, _9 `' x
    结果:5 i! D7 E& T5 ?5 U  @( A

    8 S7 ]+ @6 E$ g8 F: }) }+ D6 d2 B% x: k% b  _* }6 ?) J
    : ~& [7 d/ }& o: D; R+ y/ ~% K
    字符"?"重复前面一个匹配字符零次或者一次🍉
    , q6 W( D( W! g- U匹配结果"ab”,重复b一次 ) \' v3 L1 D5 h( g  r
    ! N) ^, V( W9 ^
    " k3 w0 x5 G4 v. Z) }
    : v+ i- ~; T, q/ x; ~% q
    import re
    , F, q- O) @4 E' g" m/ }6 n0 z0 K
    r=r"ab?"4 ]0 W' b% p- J2 |2 g3 g
    m=re.search(r,"abbcabc")
    . O# l1 C) v5 K, I: Yprint(m)5 R, {7 t1 r1 I3 A; Q$ j
    结果:1 j* v+ A6 R0 x9 J
    3 l( `, U  A7 M1 p

    : |: G' Y; ~1 t% c7 A- ~6 y# S0 I
    . d3 Q) {0 J# z6 w# ^7 l  i5 |5 ?特殊字符使用反斜杠"“引导,例如”\r"、"\n"、"\t"、"\"分别表示回车、换行、制表符号与反斜线自己本身
    2 w% v1 r3 D. @0 G# H' W) w% i6 p$ I4 o* `. \+ z' g1 l/ s  j9 Y
    import re( U% ]/ D3 x$ [
    # z+ @, i' ^6 V* \8 U/ ]
    r=r"a\nb"
    * G' j9 b# b4 b& B& e6 q3 M: z2 jm=re.search(r,"ca\nbcaba")" r' ?/ g, i. {* t3 H
    print(m)
    . b: g; m% F: m/ ? 结果:
    " Q. u9 o, y* b2 |# s5 `8 P( }& s) ^+ K$ b( Y2 H4 s$ ^+ x% K
    ) n& I2 s, X7 J) o# M. w! d
    , I0 Q" A, D; Z4 y
    完整表🔍
    " q0 q- ]/ E& U6 s# _其实上面说这些都是比较基础,比较简单的,还有复杂一点的,都在这张表里
    # j" T) E( @5 d! M) Y  m; }0 N# }# f! c

    , S) V" d7 F0 x1 w7 @  x/ o/ G' k" Y: Z0 o0 ^6 \
    match用法🤔
    , X- I1 ~4 _# r* |$ K. @match用法😃
    9 k4 `: a6 N4 L: O语法:re.match(pattern, string[, flags])  
    + P6 Z: a* m, e# I0 Z! q$ g( o& K" u
    从首字母开始开始匹配,string如果包含pattern子串,则匹配成功,返回Match对象,失败则返回None,若要完全匹配,pattern要以$结尾。
    ) Y( x! P& K3 G2 ^* A( B3 ]+ N0 X- A, x
    #示例:
    : h) S. O& ]4 d$ l5 I8 Wname='张三'
    ; h+ ^) t$ g( y6 a; A& Sif re.match('张\w+',name):
    : O! F. d5 k3 p( F/ h9 U    print('{},你好!'.format(name))
    / K4 V: z1 A2 }5 K    # 张三,你好!8 @9 j/ O# [+ \
    输出结果:张三,你好
    9 y# |3 D: m' s  y# _' x2 D
    & F, a% G1 u; r  `  k6 K# p( q# f9 l% E! U

    - J$ F# u# U( `+ R张三:谁叫我?; v9 @* Y& j0 }

    1 f7 ?. v7 [- E$ C( g不开玩笑了,继续
    : o& \: T' w" a- {
    * i: D7 x5 ~9 r8 F# i; J总的来说,match就是9 Q& \! P5 C8 p3 k" x) R2 D. b

    + W$ H7 R) _2 f$ [$ q' T1 v返回匹配的match对象
    " d2 U6 d5 s" @; O' v默认从给定字符串的开头开始匹配、即使正则表达式没有用^声明匹配开头8 A; }  [6 p% K, p8 k
    match对象🍊, \  p; Z. f$ o
    Match对象的几个属性:
    : j  I1 j* o3 j  \2 i; `/ {: H4 U) Z' a
      |, j+ o: {9 C( e# [9 c8 H! e注意,前面是有“.”的
    & L( B9 e* W) Z9 ?; [0 J8 P0 ~$ [8 e% [1..string 待匹配的文本9 I) o1 ~9 l  H
    2..re 匹配使用的pattern对象- Y; c1 o) T/ S; q& |! o
    3..pos 正则表达式搜索文本的开始位置( r  i4 A5 ]5 w: B2 o% I- A, o
    4..endpos 正则表达式搜索文本的结束位置
    . F8 b) l) i: F, Y% OMatch对象的几个方法: " v+ n% Q" N( N2 J. m
    1.group(0) 返回匹配到的子串  i0 S' i. s' A2 z" L* ]
    2.start() 返回匹配子串的开始位置
    ( u. e, b; |3 t5 n3.end() 返回匹配子串的结束位置$ s8 ?7 d9 |0 \( w- K
    4.span() 返回start()、end()/ Z4 y, |5 @5 {5 [- ]- y  U
    2 e6 S! j" J0 ]; s; q2 X% E
    数量词🍊& u: h. v& a0 M* C2 P
    $ f1 J  i4 m4 F# D0 J
    / E' B5 U7 Z7 N) a
    匹配开头、结尾🍊
    4 s7 o7 g  y/ Z$ |4 \6 d8 Q+ n/ B/ b( j' _# _; h0 M$ |
    匹配分组🔍
    $ x" ]( K0 p) `  g, W4 ~: z1 d; E5 H# P# S9 d2 C/ Z

    " ?8 u1 X4 r& q& [& h好了,看了上面几张表,其实我觉得最重要的在下面  2 V# ~# ?. Z( c: ]! z; O

    2 Y, B: `7 z* B7 c5 Ematch总结😄
    1 O2 \7 H, c# L' B/ k其实没啥好总结的,但你要看懂这张图,这个很重要
    . l' S0 B. a  P" `& h5 P: C5 U4 }

    ! e- O/ S( b- _' K' F% `* i2 {- O$ q  H) S% V3 ]' ^2 f4 o
    我框出来的是我自己感觉经常用的
    , d+ D1 w" y) m" D. P/ [& P
    9 ?2 O% \* M' v其实我自己刚学的时候也听不懂,现在觉得可简单了
    9 m+ s4 G2 d7 Z
    8 G( k7 a3 O: p7 k- f2 F; E0 m所以,你应该现在就觉得很简单吧?+ |  h# h" e' i7 S# I5 O4 W

    # R3 u, `# F; I! [; U但是,正则表达式的字符很多,容易记混,一不小心就好几十个报错,很让人崩溃
    * T! A/ Q7 c  o) r5 u, ^( j+ [
    $ \* }' H6 N" W% g8 [8 K1 L7 Z" Z; Q0 @# Y& c! ^

    : O0 ^; p5 e) m: ?# C7 R实践出真知 凸(`0′)凸 ☀️
      o3 }! B5 i9 {7 C1 G- o" R6 Q学了这么多,是不是想撸个程序了?& n4 Q" ~& X' L) `9 _- d0 ]" b
    0 h2 v$ m* A' e* [& ?) a
    已经给你准备好了: _) u# \3 Z0 Q& X& q
    9 [" i3 Q9 y7 T/ M
    程序效果:输入手机号,通过正则表达式判断手机号合不合法,
    / h( S" S9 N- ^" \2 W+ [1 z2 H
    , X' k. b1 ~1 B5 {- \) J如果合法,就输出这个手机号的信息(所属地等)1 w# F7 A- e1 b; f, i

    $ g, B9 X; `9 \  g/ Y如果不合法,就重新输入,简单吧?
    ; G, X( ]5 q# e' Q* |3 |' p7 H6 U2 T, o4 p+ S/ Y) c2 k
    这里我想重点说一下怎么获取手机号的信息3 q: W$ h$ S  v4 p: b! x7 Q1 J
    " l+ Z, g5 f1 q, o
    我一开始打算上网上百度一波的,没想到直接复制过来23个报错、我也是醉了
    , w3 }; b' S* V
    4 H, l+ V* a/ N7 }4 p3 K8 O; J
    # M6 z( z2 y4 D! V( I* Q
    5 J" G: T  A3 ^3 M哎呀,不能再发表情包了
    / [" |% e* f  q: `% J  p0 m/ ^, q! r  n

    ) Q( r2 a! Z/ o6 M" H( H/ D1 X: D+ z% o+ Q/ ^4 s
    ε=(′ο`*)))唉,还是自己写吧、、、
    : @/ ]1 w& Y' }* S" X9 d6 B- t3 L2 |$ d3 x% S
    我想起了有个模块叫phone,可以实现这个功能4 x: y5 D5 u/ l: R; V. q' U

    ; L4 y4 \4 ~8 v但是你可能还没有安装这个模块,要按命令行模式下输入pip install phone
    ; \; j* V" G7 |) _" B/ F3 b1 I0 X  A2 V
    等个六六四十九秒就下载下来了
    8 W% h5 g: I6 W3 L& H$ X& J4 \5 A& F& u
    然后你就可以体验一下了
    0 l3 `2 D  Z+ k$ p, B% [$ h" ~; ^4 m7 ?% K! t1 [
    代码(PyCharm运行通过)9 ]* K4 C9 O4 _, T& w1 M# a

    $ @' f8 O0 L1 F3 C' x- u6 Z) Oimport phone
    # D6 l) W& U8 a. Lfrom time import *& L2 g* J" m9 j2 F: e
    import re2 @; r0 u1 h/ M( x- t; F$ r; k. [

    * x5 Y7 w# f" {$ |5 Y) b% W- X2 Cdef begin():
    : I- b; S9 c: L) y) F, g    print("欢迎来到查询小程序")
    * |, f; Q5 R+ N, G5 ^5 E    print("1.查询")
    3 V. d+ p. h4 B0 L! I    print("2.用户")
    : p9 E, c& Q& C0 h
    7 J& a$ c( U$ f* c" P! y7 y/ x0 x; f
    def p(n):
    * M9 C- i$ E4 _& O: ]$ i    if re.match(r'1[3,4,5,7,8]\d{9}', n):( b* X. P) Q; A
            if re.match(r'13[0,1,2]\d{8}', n) or \
    % X. B; C8 q  P5 e0 l- Q! X                re.match(r"15[5,6]\d{8}", n) or \
    " s& z6 E5 F/ G3 w) U$ b8 p4 o                re.match(r"18[5,6]", n) or \! z" M3 \, t  v& Q8 J9 |
                    re.match(r"145\d{8}", n) or \
    " i( P' F  }8 f/ Q; G; `- b                re.match(r"176\d{8}", n):9 q  q7 X8 }) t+ |
                return True- }! K- E8 F2 @
            elif re.match(r"13[4,5,6,7,8,9]\d{8}", n) or \' S" \; k" N! y% w9 P% \5 a
                    re.match(r"147\d{8}|178\d{8}", n) or \
    0 T& ]' u' U$ C: R                re.match(r"15[0,1,2,7,8,9]\d{8}", n) or \0 w7 r- m7 C3 ]" R. c! H
                    re.match(r"18[2,3,4,7,8]\d{8}", n):7 S' x# ]9 H1 I6 I0 @4 w2 i+ B0 a
                return True7 _' E% F+ c) L, t, m/ h
            else:
    ) c% r$ \) ^( x  z% W            return True+ F8 M  |! v( p0 @) j1 d5 w
        else:
    3 ^& e, L5 S7 ]7 T' A        return False* W2 G' I& n' u( ?
    * d4 E2 H" D: S
    if __name__ == "__main__":: s. V, U# @8 t  H: G
        s=0
    + |' y' N3 Q8 Z$ e    begin()
    : q8 l" |! \1 W6 C/ H! n    while True:: O1 T# Q* s! X6 t* }3 g# K% V& K
            op = int(input("请输入:"))
    6 W5 I5 g) Y& n+ D6 P% p* S        if op==1:
    * K: u' u& R6 W2 q1 r, o; P            phoneNum = str(input("请输入你的电话号码"))
    , P5 A% Z- {6 b            if p(phoneNum)==False:
    # x' n& V; s' D/ c7 K2 q                print("该手机号无效")" w+ t  Y' q3 ?% _' P) X9 v% _8 s
                    for i in range(100):& M0 D9 a% z: i( x* y! G7 q/ `  y' P
                        print('\n')
    7 P! C7 B* {" L9 X                begin()- z& s: }; m9 u. ~7 c& u! Y
                else:8 P. O; p/ t- d* r: [2 J7 f- K
                    info = phone.Phone().find(phoneNum)
    ! m' Q& C$ |* k/ U6 Q                print("手机号码:"+str(info["phone"]))
    0 o6 s! }. U3 h$ D8 e                print("手机所属地:"+str(info["province"])+"省"+str(info["city"])+"市")$ i4 v- i6 a  E+ k6 c/ o- H# P
                    print("邮政编号:"+str(info["zip_code"]))5 B) g- B3 v! L
                    print("区域号码:"+str(info["area_code"]))
    ; L8 P  t. o9 }8 c+ L$ o8 O5 g, y                print("手机类型:"+str(info["phone_type"]))
    6 C* c, }7 ^. ^- k                s+=1
    - B* s: y2 ^/ j4 R8 y                i = input("输入任意数退出...")
    : t0 b% R2 W* I# p% l                for i in range(100):
    5 s3 _! Z" w3 Y  _                    print('\n')6 Q! b( r3 ?* F
                    begin()
    . M7 Q' l( p$ u& U0 |        if op==2:& o" f6 q. D- }9 h# g& z9 T/ P
                print("使用次数:"+str(s))
    * i; U) e  T$ }: D            i = input("输入任意数退出...")
    . ]; X. l4 `. }) L, w+ y! \            for i in range(100):# b" o! n- t% ~$ O8 ]& q
                    print('\n')" U) z* e7 U9 Q5 j' g0 N- F7 @
                begin()2 V* T  K+ s0 ?/ S$ ~( Z

    4 F/ D1 \9 |+ ~$ J2 H# f写在最后🧐
    / N% t5 G7 W* _$ L' `" }————————————————
    2 S( \# Q( l# @+ J" {  V版权声明:本文为CSDN博主「YR_T」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。& Z! S" ~) o  g7 U
    原文链接:https://blog.csdn.net/m0_64036070/article/details/123853489
    3 z- ^$ J% J! h% ]' Q* _
    3 X, S9 j6 F, i! l) Q0 @: L* G3 m9 `/ 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-7-28 19:33 , Processed in 0.398952 second(s), 50 queries .

    回顶部