第一节    正则表达式的一些介绍

1)掌握正则表达式的案例

2)写一个小爬虫

3)正则表达式(或RE)是一个小型的、高度专业化的编程语言,(在python中)它内嵌在python中,并通过re模块实现。

    - 可以为想要匹配的相应字符串集指定规则

    - 该字符串集可能包含英文语句、e-mail地址、命令或任何你想搞定的东西

    - 可以问诸如“这个字符串匹配该模式吗?”

    - “在这个字符串中是否有部分匹配该模式呢?”

    - 你也可以使用RE以各种方式来修改或分割字符串。

4)正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行

5)正则表达式语言相对小型和受限(功能有限)

    - 并非所有字符串处理都能用正则表达式完成

6)字符匹配

    - 普通字符

        a.大多数字母和字符一般都会和自身匹配

        b.如正则表达式test会和字符串“test”完全匹配

    - 元字符

        .    ^    $    *    +    ?    { }    [ ]    \    |    ( )

    A.[ ]

        - 常用来指定一个字符集:[abc];[a-z]

        - 元字符在字符集中不起作用:[akm$]

        - 补集匹配不在区间范围内的字符:[^5]

    B.^

        - 匹配行首。除非设置MULTILINE标志,它只是匹配字符串的开始。在MULTILINE模式里,它也可以直接匹配字符串中的每个换行。

        - 匹配行尾,行尾被定义为要么是字符串尾,要么是一个换行字符后面的任何位置。

>>> import re 
>>> s = r'abc' 
>>> 
>>> re.findall(s,"aaaaaaaaaaaaa") 
[] 
>>> re.findall(s,"a") 
[] 
>>> re.findall(s,"abcaaaaaaaaaaaaaaaaaaa") 
['abc'] 
>>> re.findall(s,"abcaaaaaaaaaaaaaaaaaaabc") 
['abc', 'abc'] 
>>> 
>>> st = "top tip tqp twp tep" 
>>> 
>>> res = r"top" 
>>> re.findall(res,st) 
['top'] 
>>> res = r"tip" 
>>> re.findall(res,st) 
['tip'] 
>>> 
>>> res = r"t[io]p" 
>>> re.findall(res,st) 
['top', 'tip'] 
>>> res = r"t[^io]p" 
>>> re.findall(res,st) 
['tqp', 'twp', 'tep']

现在我们以匹配

>>> s = "hello world,hello boy" 
>>> 
>>> r = r"hello" 
>>> re.findall(r,s) 
['hello', 'hello'] 
>>> re.findall(r,'t^') 
[] 
>>> r = "t[abc$]"        以什么结尾 
>>> 
>>> re.findall(r,'ta') 
['ta'] 
>>> re.findall(r,'tb') 
['tb'] 
>>> re.findall(r,'tax') 
['ta'] 
>>> re.findall(r,'t$') 
['t$']

>>> r = r"x[0123456789]x"

>>> r = r"x[0-9]x"            #通过正则表达式我们可以这样写 
>>> r = r"x[a-zA-Z]x" 
>>> r = r"x[a-zA-Z0-9]x"

>>> re.findall(r,'x1x') 
['x1x'] 
>>> re.findall(r,'x2x') 
['x2x'] 
>>> re.findall(r,'x9x') 
['x9x']

第二节     

>>> r = r"^abc" 
>>> 
>>> import re 
>>> re.findall(r,'abc') 
['abc']

>>> r = r"\^abc"        这里我们使用\来做转义 
>>> import re

>>> re.findall(r,'^abc ^abc ^abc')        这里就可以匹配到r里面的^abc这个字符串

['^abc', '^abc', '^abc']

1)\

    - 反斜杠后面可以加不同的字符以表示不同特殊意义

    - 也可以用于取消所有的元字符:\[ 或 \\

        \d    匹配任何十进制数;它相当于类[0-9].

        \D    匹配任何非数字字符;它相当于类[^0-9]。

        \s     匹配任何空白字符;它相当于类[\t\n\r\f\v]。

        \w    匹配任何字母数字字符;它相当于类[a-zA-Z0-9_]。

        \W    匹配任何非字母数字字符;它相当于类[^a-zA-Z0-9]。

>>> r = "[0-9]" 
>>> re.findall(r,'1234567890') 
['1', '2', '3', '4', '5', '6', '7', '8', '9', '0'] 
>>> r = "\d"            这里我们使用了\d,它就表示[0-9] 
>>> re.findall(r,'1234567890') 
['1', '2', '3', '4', '5', '6', '7', '8', '9', '0']

 
下面我们做一个对电话号码进行匹配查询:

>>> import re

>>> 010-12345678 
-12345670 
>>> r= r"^010-\d\d\d\d\d\d\d\d"

>>> re.findall(r,'010-87654321')

['010-87654321']

>>> r= r"^010-\d{8}"            我们可以使用{}来指定前面的\d出现的次数,可以达到同样的效果 
>>> re.findall(r,'010-87654321')         
['010-87654321']

2)重复

    - 正则表达式第一功能是能够匹配补丁长的字符集,另一个功能就是你可以指定正则表达式的一部分的重复次数。

3)*

    - 指定前一个字符可以被匹配零次或多次,而不是只有一次。匹配引擎会试着重复尽可能多的次数(不超过整数界定范围,20亿)

    - a[bcd]*b-- "abcbd"

>>> r = r"ab*" 
>>> re.findall(r,'a') 
['a'] 
>>> re.findall(r,'ab') 
['ab'] 
>>> re.findall(r,'abbbbb') 
['abbbbb']

4)+

    - 表示匹配一或更多次。

    - 注意*和+之间的不同;*匹配零或更多次,所以可以根本就不出现,而+则要求至少出现依次

5)?

    - 匹配一次或零次;你可以认为它用于标识某事物是可选的

>>> r = r"ab+" 
>>> re.findall(r,'a') 
[] 
>>> re.findall(r,'ab') 
['ab'] 
>>> re.findall(r,'abb') 
['abb'] 
>>> re.findall(r,'abbbbbbb') 
['abbbbbbb']

下面我们来匹配一个字符串电话号码:

>>> r = r"^010-?\d{8}$"        ?在这里表示前面的那个-是可有可无的

>>> re.findall(r,'01012345678') 
['01012345678'] 
>>> re.findall(r,'010-12345678') 
['010-12345678'] 
>>> re.findall(r,'010--12345678')            我们看一下这样就不行了,这样就达到了我们的要求

[]

在正则表达式匹配中有一个贪婪模式和一个非贪婪模式:         

>>> r = r"ab+"        贪婪模式,将后面多个b同时会输出

>>> 
>>> re.findall(r,'abbbbbbbbb') 
['abbbbbbbbb'] 
>>> r = r"ab+?"        非贪婪模式做最小匹配 
>>> re.findall(r,'abbbbbbbbb') 
['ab']

6){m,n}

    - 其中m和n是十进制整数。该限定符的意思是至少有m个重复,至多到n个重复。a/{1,3}b

    - 忽略m会认为下边界是0,而忽略n的结果将是上边界为无穷大(实际上是20亿)

    - {0,}等同于*,{1,}等同于+,而{0,1}则与?相同。如果可以的话,最好使用*,+,或?

>>> r = r"a{1,3}" 
>>> re.findall(r,'a') 
['a'] 
>>> re.findall(r,'b') 
[] 
>>> re.findall(r,'aa') 
['aa'] 
>>> re.findall(r,'aaa') 
['aaa'] 
>>> re.findall(r,'aaaa') 
['aaa', 'a']

第三节    正则表达式常用函数

1)使用正则表达式

    - re模块提供了一个正则表达式引擎的接口,可以让你将REstring编译成对象并用它们来进行匹配。

    - 编译正则表达式

    hy@hy:~$ python

    >>> import re

    >>> p = re.compile('ab*') 
    >>> print p 
    <_sre.SRE_Pattern object at 0x7f66cc831c00>

以我们上节的匹配电话号码的方法

>>> import re

>>>

>>> r1 = r"\d{3,4}-?\d{8}" 
>>> re.findall(r1,"010-12345678") 
['010-12345678'] 
>>> re.findall(r1,"010-1234567") 
[]

>>> p_tel=re.compile(r1)        我们将前面定义好的这个r1进行编译,

>>> p_tel 
<_sre.SRE_Pattern object at 0x7f66cc7d89d0> 
>>> p_tel.findall('010-12345678')   编译好的正则要比未编译的正则匹配起来的速度要快很多 
['010-12345678'] 
>>> p_tel.findall('010-123456789') 
['010-12345678']

    - re.compile90也接受可选的标志参数,常用来实现不同的特殊功能和语法变更

    hy@hy:~$ python

    >>> py_re = re.compile(r'py',re.I) 
    >>> py_re.findall('PY') 
    ['PY'] 
    >>> py_re.findall('py') 
    ['py'] 
    >>> py_re.findall('Py') 
    ['Py'] 
    >>> py_re.findall('pY') 
    ['pY']

    - 反斜杠的麻烦

        a.字符串前面加“r”反斜杠就不会被任何特殊方式处理

        

    b.执行匹配

        - `RegexObject`实例有一些方法和属性,完整的列表可查询Python Library Reference

         

                如果没有匹配到的话,match()和search()将返回None。

                如果成功的话,就会返回一个`MatchObject`实例,

>>> py_re.match('py hello')        我们可以看到使用match去匹配的时候,它会返回一个对象

<_sre.SRE_Match object at 0x7f66cc6dd440>   这个对象当中其实是包含py这个字符串的

>>> py_re.match('hello')         当我们去掉py这个字符串或将它放在后面的时候它返回值为空
>>> py_re.match('hello py')

下面我们使用search去匹配,我们会发现它不管匹配元素在什么位置,只要有都可以找到:

>>> x = py_re.match('hello py') 
>>> if x : 
...     pass 
... 
>>> py_re.search('hello py') 
<_sre.SRE_Match object at 0x7f66cc6dd4a8> 
>>> py_re.search('py hello') 
<_sre.SRE_Match object at 0x7f66cc6dd440> 
>>> py_re.search('py hello   ')

<_sre.SRE_Match object at 0x7f66cc6dd4a8>

下面我们看一下finditer这个方法: 

>>> py_re.findall('hello py hello') 
['py'] 
>>> py_re.findall('hello py hello py py') 
['py', 'py', 'py'] 
>>> py_re.finditer('hello py hello py py') 
<callable-iterator object at 0x7f66cc6e8a50>        它返回的是一个迭代器的对象,

>>> x = py_re.finditer('hello py hello py py')            这里我们定义x是他的一个迭代对象        
>>> x.next()   迭代对象,我们想看他里面的方法的话,可以使用它里面的一个方法next()
<_sre.SRE_Match object at 0x7f66cc6dd4a8>

    - MatchObject实例方法

         

    c.实际程序中,最常见的作法是将`MatchObject`保存在一个变量里,然后检查它是否为None
>>> x = py_re.match('py hello') 
>>> x 
<_sre.SRE_Match object at 0x7f66cc6dd440>

>>> x.group()        使用group()这个方法就可以看到py这个数据了
'py' 
       d.模块级函数

        - re模块也提供了顶级函数调用如match()、search()、sub()、subn()、split()、findall()等

>>> rs = r'p..y'

>>> re.sub(rs,'python','paby pooy phky ccccc')        输出符合p..y 规则的字符串被替换 
'python python python ccccc'    这里我们看到这个字符串的输出结果符合p..y这个规则的替换

>>> re.subn(rs,'python','paby pooy phky ccccc')            这个会输出替换了多少次 
('python python python ccccc', 3) 
>>> ip = "1.2.3.4"

>>> ip.split('.')        我们可以对ip以'.'进行切割

['1', '2', '3', '4'] 
>>> s = "123+456-789*000" 
>>> 
>>> re.split(r'[\+\-\*]',s)            我们使用正则对其进行不同分隔符的指定 
['123', '456', '789', '000']

>>> dir(re)            列出一些re的方法

['DEBUG', 'DOTALL', 'I', 'IGNORECASE', 'L', 'LOCALE', 'M', 'MULTILINE', 'S', 'Scanner', 'T', 'TEMPLATE', 'U', 'UNICODE', 'VERBOSE', 'X', '_MAXCACHE', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__version__', '_alphanum', '_cache', '_cache_repl', '_compile', '_compile_repl', '_expand', '_pattern_type', '_pickle', '_subx', 'compile', 'copy_reg', 'error', 'escape', 'findall', 'finditer', 'match', 'purge', 'search', 'split', 'sre_compile', 'sre_parse', 'sub', 'subn', 'sys', 'template']

>>> help(re)        re的更多用法可以使用help去查看

第四节    正则表达式内置属性及分组

1)编译标志-flags

>>> r1 = r"py.net" 
>>> 
>>> re.findall(r1,'py.net') 
['py.net'] 
>>> re.findall(r1,'pyonet') 
['pyonet'] 
>>> re.findall(r1,'py\nnet') 
[] 
>>> re.findall(r1,'py\nnet',re.S) 
['py\nnet'] 
>>> re.findall(r1,'py\tnet',re.S) 
['py\tnet']

M多行匹配,影响^或$:

>>> import re 
>>> s = """ 
... hello py 
... py hello 
... hello py hello 
... py hello

... """

>>> s 
'\nhello py\npy hello\nhello py hello\npy hello\n'

>>> r = r"^py"

>>> re.findall(r,s,re.M)        使用正则的M这个多行匹配属性

['py', 'py']

我们使用re.X匹配正则:


>>> tel = r""" 
... \d{3,4} 
... -? 
... \d{8} 
... """

>>>

>>> re.findall(tel,'010-123456787') 
[]

>>> re.findall(tel,'010-123456787',re.X)     使用正则的X属性匹配电话号码 
['010-12345678']

可以使用VERBOSE这个属性如上面的,下面是对相应的属性做的相应的说明
>>> charef = re.compile(r"""

... ( 
... [0-9]+[^0-9]        #Decimal form 
... |0[0-7]+[^0-7]      #Octal form 
... |x[0-9a-fA-F]+[^0-9a-fA-F] #Hexadecimal form 
... """,re.VERBOSE)

2)分组

    - "("和")"

>>> email=r"\w{3}@\w+(\.com|\.cn)"      我们在这里定义一个email以.com或.cn结尾

>>>               这里我们(定义了一个分组) 
>>> re.match(email,'zzz@hyserver.com')        匹配以.com结尾成功 
<_sre.SRE_Match object at 0x7f30724615d0> 
>>> re.match(email,'zzz@hyserver.cn')            匹配以.cn结尾成功 
<_sre.SRE_Match object at 0x7f3072461648> 
>>> re.match(email,'zzz@hyserver.org')           匹配以.org结尾失败 
>>>

>>> re.findall(email,'zzz@hyserver.com')            当我们做匹配的时候

['.com']                                 还会优先的返回分组当中的数据

下面我们看一下其他类型的匹配:


>>> s = r""" 
... hhsdj dskj hello src=csvt yes jdjsds 
... djhsjk src=123 yes jdsa 
... src=234 yes 
... hello src=python yes ksa 
... """

>>> print s

hhsdj dskj hello src=csvt yes jdjsds 
djhsjk src=123 yes jdsa 
src=234 yes 
hello src=python yes ksa

>>> r1 = r"hello src.+ yes"

>>> re.findall(r1,s)        通过r1这样的匹配可以很好的找到里面对应的数据

['hello src=csvt yes', 'hello src=python yes']  
>>> r1= r"hello src=(.+) yes"    我们也可以将里面的.+定义成一个分组然后进行相应的匹配,它就会只返回=后面的数据,这样我们在做爬虫的时候,对网页的某个值进行提取 
>>> re.findall(r1,s) 
['csvt', 'python']

第五节    一个小爬虫

1)下载贴吧或空间中所有图片
hy@hy:~/Documents/py/jpg$ vim getjpg.py 
  1 #!/usr/bin/python 
  2 import re 
  3 import urllib 
  4 
  5 def getHtml(url): 
  6     page = urllib.urlopen(url) 
  7     html = page.read() 
  8     return html 
  9 
 10 def getImg(html): 
 11     reg = r'src="(.*?\.jpg)" width' 
 12     imgre = re.compile(reg) 
 13     imglist = re.findall(imgre,html) 
 14     x = 0 
 15     for imgurl in imglist: 
 16         urllib.urlretrieve(imgurl,'%s.jpg' % x) 
 17         x+=1 
 18     return imglist 
 19 
 20 html = getHtml("http://image.baidu.com/i?tn=baiduimage&ct=201326592&lm=-1&cl=2&word=%CD%BC%C6%AC&fr=ala&ala=1&alatpl=others&pos=0") 
 21 getImg(html)

hy@hy:~/Documents/py/jpg$ python getjpg.py

hy@hy:~/Documents/py/jpg$ ls 
0.jpg   12.jpg  15.jpg  18.jpg  20.jpg  23.jpg  26.jpg  3.jpg  6.jpg  9.jpg 
10.jpg  13.jpg  16.jpg  19.jpg  21.jpg  24.jpg  27.jpg  4.jpg  7.jpg  getjpg.py 
11.jpg  14.jpg  17.jpg  1.jpg   22.jpg  25.jpg  2.jpg   5.jpg  8.jpg

这样我们就将这个网页上所有以.jpg结尾的图片下下来了。

第六节    数据结构之深拷贝和浅拷贝

python对内存的使用

    - 所谓浅拷贝就是对引用的拷贝(只拷贝父对象)

    - 所谓深拷贝就是对象的资源的拷贝

    - 解释一个例子:

>>> a = [1,2,3,'a','b','c'] 
>>> 
>>> b = a 
>>> b 
[1, 2, 3, 'a', 'b', 'c'] 
>>> a 
[1, 2, 3, 'a', 'b', 'c'] 
>>> 
>>> id(a) 
139845710543400 
>>> id(b) 
139845710543400

>>> a.append('d')        因为b和a指向的是同一个地址空间,所以我们在改变a的时候b也会改变

>>> a 
[1, 2, 3, 'a', 'b', 'c', 'd'] 
>>> b 
[1, 2, 3, 'a', 'b', 'c', 'd']

>>> b.append(4)            我们去改变b也是同样的道理

>>> b 
[1, 2, 3, 'a', 'b', 'c', 'd', 4] 
>>> a

[1, 2, 3, 'a', 'b', 'c', 'd', 4]

下面我们来看一下如何实现拷贝 

>>> import copy        首先我们要导入一个copy模块

>>> 
>>> a = [1,2,3,['a','b','c']] 
>>> b=a 
>>>

>>> c = copy.copy(a)        调用copy这个模块里面的copy方法

>>> b 
[1, 2, 3, ['a', 'b', 'c']] 
>>> c 
[1, 2, 3, ['a', 'b', 'c']] 
>>> id(a) 
139845710626400 
>>> id(b) 
139845710626400

>>> id(c)                        由于c是copy过来的,所以它的地址空间和a是不同的

139845710722040

>>> a.append('d')           然后我们通过给a里面增加一个值,看看c是否改变

>>> a 
[1, 2, 3, ['a', 'b', 'c'], 'd'] 
>>> b 
[1, 2, 3, ['a', 'b', 'c'], 'd'] 
>>> c

[1, 2, 3, ['a', 'b', 'c']]  在这里我们发现c列表里面的值没有改变,这里的拷贝就是一个浅拷贝,只拷贝父对象

>>> id(a[0])            但是我们会发现a和c里面的元素还是指向同一个空间的

16290136 
>>> id(c[0])

16290136

下面让我们看一下拷贝的时候的内存空间的分配: 

>>> a[3].append('d')            我们来测试,改变a里面的元素,看看c元素是否改变

>>> a 
[1, 2, 3, ['a', 'b', 'c', 'd'], 'd'] 
>>> c

[1, 2, 3, ['a', 'b', 'c', 'd']]        这里我们发现c里面的相应的元素也改变了

下面我们做一个深拷贝:

>>> d=copy.deepcopy(a)         
>>> d 
[1, 2, 3, ['a', 'b', 'c', 'd'], 'd'] 

>>> id(a[3])                    我们来看看a和d中的一个元素的地址空间

139845710626688 
>>> id(d[3])     
139845710721824        我们发现这时已经不是同一个地址空间了

>>> a.append('e')            我们再去测试给a增加一个元素,看看d是否有变化

>>> a 
[1, 2, 3, ['a', 'b', 'c', 'd'], 'd', 'e'] 
>>> d

[1, 2, 3, ['a', 'b', 'c', 'd'], 'd']            我们可以看到d没有变化

转载于:https://www.cnblogs.com/hyserver/p/4498256.html

第五章 python中正则表达式的使用相关推荐

  1. Python中正则表达式用法 重点格式以这个为准_首看_各种问题

    20210811 https://www.jb51.net/article/101258.htm 一.惰性模式的概念: 此模式和贪婪模式恰好相反,它尽可能少的匹配字符以满足正则表达式即可,例如: va ...

  2. 第五章 Python数据结构

    第五章 Python数据结构 本章更详细地讨论一些已经讲过的数据类型的使用,并引入一些新的类型. 5.1 列表 列表数据类型还有其它一些方法.下面是列表对象的所有方法: insert(i, x) -- ...

  3. 第十五章 Python和Web

    第十五章 Python和Web 本章讨论Python Web编程的一些方面. 三个重要的主题:屏幕抓取.CGI和mod_python. 屏幕抓取 屏幕抓取是通过程序下载网页并从中提取信息的过程. 下载 ...

  4. Python入门 - 笔记 - 第三章 Python中的变量和数据类型

    第三章 Python中的变量和数据类型 -------------------------------------------------------------------------------- ...

  5. python中正则表达式_Python中正则表达式详解

    正则表达式是用来简洁表达一组字符串的表达式,本文主要和大家分享Python 中正则表达式知识详解,希望能帮助到大家.操作符说明实例.表示任何单个字符 [ ]字符集,单个字符取值范围[abc]表示a或b ...

  6. python中正则表达式的简单应用_Python正则表达式详细应用

    原文地址:http://www.jb51.net/article/65286.htm 1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合, ...

  7. 《SVN宇宙版教程》:第五章 TortoiseSVN中Repo-browser介绍

    第五章 TortoiseSVN中Repo-browser介绍 导言: 窗口Repo-browser是TortoiseSVN提供的一个管理工作副本或仓库文件的工具,此窗口在使用TortoiseSVN工具 ...

  8. 站长在线Python精讲:Python中正则表达式的语法详解

    欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是<Python中正则表达式的语法详解>.本知识点主要内容有9点:行定位符.元字符.限定符.字符集.排除字符.选择字符.转义字符 ...

  9. 第五章 Java 中的 wait、notify 和 notifyAll 方法示例

    您可能已经注意到 Object 类具有三个 final 方法,分别称为 wait.notify 和 notifyAll.这些方法用于线程间通信.Java 5 引入了执行器框架,它为您处理线程间通信,并 ...

最新文章

  1. linux 查找大文件
  2. Python 程序扩展名(py, pyc, pyw, pyo, pyd) 及发布程序时的选择
  3. 使用 file_get_contents 获取网站信息报错failed to open stream: HTTP request failed!
  4. java使用内部类的好处及其初始化
  5. 新概念51单片机C语言教程纠错(1)
  6. Shell in AIX Web端 自动远程执行重启tomcat服务命令
  7. 【html、CSS、javascript-9】jquery-选择器及过滤器
  8. app客户端上传图片实现方式
  9. 在windows的命令行窗口打开.ipynb文件
  10. 算法——指定日期的星期推算
  11. SpringBoot整合Quartz之动态控制任务(暂停,启动,修改执行时间)
  12. keepass使用坚果云管理我的密码
  13. 产品名称:iWX JAVA微信管理平台源码-微友1314
  14. Java中多态、重写方法、instanceof运算符、重写equals的相关案例
  15. 《互联网金融投资理财一册通》一一1.1 互联网金融
  16. 去掉goland中间的令人烦躁的竖线
  17. 英飞凌TRAVEO II介绍
  18. PC 端微信逆向分析
  19. linux樱桃树软件名字,名字带“樱”的3种水果,多数人最先想到樱桃,第3种最少见!...
  20. 行业专网应用频段分析

热门文章

  1. WinForm 应用程序中开启新的进程及控制
  2. 天天向上 专访Data Domain创始人李凯
  3. 【EXLIBRIS】随笔记 001
  4. C# where用法
  5. 如何从机器学习数据中获取更多收益
  6. 面向对象和结构化程序设计的区别X
  7. mybatis.xml
  8. 3.Linux文件与目录管理
  9. 从零开始学习 webservice第一集,java webservice简单实例入门教程
  10. 一个基于poi的excel导出程序