首页 > 代码库 > python学习之路——基础篇(3)模块(续)

python学习之路——基础篇(3)模块(续)

re正则表达式、shutil、ConfigParser、xml

一、re

  • 正则元字符和语法:
语法 说明   表达式 完全匹配字符
          字符
一般字符   匹配自身 abc   abc
. 匹配除换行符“\n”外,任意一个字符 a.c abc
\       转义字符,将特殊字符转义为本身

a\.c

a\\c

a.c

a\c

[...]

匹配字符集任意一个字符,或者“-”表示一个集合范围

如:[a-zA-Z0-9]匹配范围中任意一个字符;或者[^]

匹配否定,对括号中的内容取反。

[abc]efg

aefg

befg

cefg

         预定义字符集
\d 数字:[0-9] a\dc a1c
\D 非数字:[^\d] a\Dc abc
\s 空白字符:[<空格>\t\r\n\f\v] a\sc a c
\S 非空白字符:[^\s] a\Sc abc
\w 字符:[a-zA-Z0-9_]   a\wc abc
\W  非单词字符:[^\w] a\Wc a c
                           数量词
*   匹配前一个字符0次或无数次 a*b

aab

ab

b

+   匹配前一个字符1次或无数次 a+b

aab

aaaab

? 匹配前一个字符0次或1次 a?b

b

ab

{m} 匹配前一个字符m次 a{2}c aac
{m,n}

匹配前一个字符m次到n次。m与n可以省略

如果省略m,表示0次到n次;省略n表示从m次到

无数次

a{1,2}c

ac

aac

*? +? ??

{m,n}?

使*、+、?、{m,n}变为非贪婪模式 见后文
                    边界匹配
^ 匹配字符串开头 ^abc abc
$ 匹配字符串结尾 abc$ abc
\A 仅匹配字符串开头 \Aabc abc
\Z 仅匹配字符串结尾 abc\Z abc
\b
匹配一个单词边界,也就是指单词和空格间的位置。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”
ab\b ab
\B
匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”
ab\Bc abc
                    逻辑与分组
|

代表左右表达式任意匹配一个。

它总是先匹配左边的,一旦匹配成功,则跳过右边表达式。

如果|没有被包含在()中,他的范围将是整个表达式。

abc|def

abc

def

()

被括号括起来的表达式将视为分组。

从表达式左边开始,每遇到一个分组的左括号“(“,编号+1

分组表达式作为一个整体,可以后接数量词。表达式中|仅在分组中生效。

(abc){2}

(abc|bcd)

abcabc

abc

(?P<name>...) 分组,除了原有编号外,再指定一个别名。group(1)=group(name) (?P<id>abc) abc
(?P=name)引用别名为name的分组匹配到的字符串(?P<id>123)abc(?P=id)123abc123
  • 数量词的贪婪模式与非贪婪模式

  正则表达式通常用于在文本中查找匹配的字符串。Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪的则相反,总是尝试匹配尽可能少的字符。例如:正则表达式"ab*"如果用于查找"abbbc",将找到"abbb"。而如果使用非贪婪的数量词"ab*?",将找到"a"。

  • 反斜杠的困扰

  与大多数编程语言相同,正则表达式里使用"\"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符"\",那么使用编程语言表示的正则表达式里将需要4个反斜杠"\\\\":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r"\\"表示。同样,匹配一个数字的"\\d"可以写成r"\d"。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

  • re相关匹配方法
  1. match

    match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None

    

 1 import re
 2 
 3 text="the Attila the Hun show"
 4 m = re.match(".",text)
 5 print(m.group()) #"t" 或者group(0)取得匹配所有结果
 6 
 7 m = re.match("(.)(.)(.)",text)
 8 print(m.group(0)) #"the"
 9 
10 #分组
11 print(m.group(1,2,3)) #(‘t‘,‘h‘,‘e‘) 匹配后得分组
12 
13 #将正则编译成Pattern对象
14 pattern = re.compile(".") 
15 m = pattern.match(text)
16 print(m.group()) #‘t‘

 

  2. search

    search, 浏览整个字符串去匹配第一个,未匹配成功返回None

1 import re
2 text = "Example 3:there is 1 date 11/5/2016 in here"
3 m = re.search("(\d{1,2})/(\d{1,2})/(\d{2,4})",text)
4 print(m.group(1),m.group(2),m.group(3))# 11 5 2016

     3. sub

    替换匹配成功的指定位置字符串

 1 import re
 2 # sub(pattern, repl, string, count=0, flags=0)
 3 # pattern: 正则模型
 4 # repl   : 要替换的字符串或可执行对象
 5 # string : 要匹配的字符串
 6 # count  : 指定匹配个数
 7 # flags  : 匹配模式
 8 text = "you‘re no fun anymore fun"
 9 m = re.sub("fun","entertaining",text,2)
10 print(m)
11 # "you‘re no entertaining anymore entertaining"

    4. spilt

          根据正则匹配分隔字符串

import re
# split(pattern, string, maxsplit=0, flags=0)
# pattern: 正则模型
# string : 要匹配的字符串
# maxsplit:指定分割个数
# flags  : 匹配模式

# 无分组
origin = "hello alex bcd alex lge alex acd 19"
r = re.split("alex", origin, 1)
print(r) #["hello","bcd alex lge alex acd 19"]

# 有分组
origin = "hello alex bcd alex lge alex acd 19"
r1 = re.split("(alex)", origin, 1)
print(r1) # ["hello","alex","bcd alex lge alex acd 19"]

 r2 = re.split("(al(ex))", origin, 1)
print(r2) # ["hello","alex","ex","bcd alex lge alex acd 19"]

    5. findall

    获取非重复的匹配列表;如果有一个组则以列表形式返回,且每一个匹配均是字符串;如果模型中有多个组,则以列表形式返回,且每一个匹配均是元祖;

    空的匹配也会包含在结果中
1 # 无分组
2 origin = "hello alex bcd abcd lge acd 19"
3 r = re.findall("a\w+",origin)
4 print(r) # ["alex","abcd","acd"]
5 
6 # 有分组
7 origin = "hello alex bcd abcd lge acd 19"
8 r = re.findall("a((\w*)c)(d)", origin)
9 print(r) # 匹配两个字符串"abcd"&"acd"先将匹配最外层分组的元素放入元祖#中,再将内层分组匹配的元素放入元祖中结果[("bc","b","d"),("c","","d")] 
IP:
^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$
手机号:
^1[3|4|5|8][0-9]\d{8}$
邮箱:
[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+

二、shutil

高级文件、文件夹、压缩包处理模块

  1. 将文件内容拷贝到另一个文件

    shutil.copyfileobj(fsrc, fdst[, length])

1 import shutil
2 shutil.copyfileobj(open(old.xml,r), open(new.xml, w))

  2. 拷贝文件

    shutil.copyfile(src, dst)

1 shutil.copyfile(f1.log, f2.log)

  3. 仅拷贝权限。内容、组、用户均不变

    shutil.copymode(src, dst)

1 shutil.copymode(f1.log, f2.log)

  4. 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags

    shutil.copystat(src, dst)

1 shutil.copystat(f1.log, f2.log)

  5. 拷贝文件和权限

    shutil.copy(src, dst)

1 shutil.copy(f1.log, f2.log)

  6. 拷贝文件和状态信息

    shutil.copy2(src, dst)

1 shutil.copy2(f1.log, f2.log)

  7. 递归的去拷贝文件夹

    shutil.ignore_patterns(*patterns) 忽略某些格式文件
    shutil.copytree(src, dst, symlinks=False, ignore=None)

1 import shutil
2 shutil.copytree(folder1, folder2, ignore=shutil.ignore_patterns(*.pyc, tmp*))
1 import shutil
2 shutil.copytree(f1, f2, symlinks=True, ignore=shutil.ignore_patterns(*.pyc, tmp*))

 8. 递归的去删除文件

    shutil.rmtree(path[, ignore_errors[, one rror]])

1 import shutil
2 shutil.rmtree(folder1)

  9. 递归的去移动文件,它类似mv命令,其实就是重命名。

    shutil.move(src, dst)

1 import shutil
2 shutil.move(folder1, folder3)

  10. 创建压缩包并返回文件路径,例如:zip、tar

    shutil.make_archive(base_name, format,...) 这个功能只能压缩一个文件夹

  • base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,如:www =>保存至当前路径如:/Users/lcy/www =>保存至/Users/lcy/
  • format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
  • root_dir: 要压缩的文件夹路径(默认当前目录)
  • owner: 用户,默认当前用户
  • group: 组,默认当前组
  • logger: 用于记录日志,通常是logging.Logger对象  
#将 /Users/lcy/Downloads/test 下的文件打包放置当前程序目录
import shutil
ret = shutil.make_archive("www", gztar, root_dir=/Users/lcy/Downloads/test)
#将 /Users/lcy/Downloads/test 下的文件打包放置 /Users/lcy/目录
import shutil
ret = shutil.make_archive("/Users/lcy/www", gztar, root_dir=/Users/lcy/Downloads/test)

附加:ZipFile 和 TarFile一般用这个较多

 1 import zipfile
 2 
 3 # 压缩
 4 z = zipfile.ZipFile(laxi.zip, w) #创建一个压缩包
 5 z.write(a.log)
 6 z.write(data.data)
 7 z.close()
 8 # 解压
 9 z = zipfile.ZipFile(laxi.zip, r)
10 z.extractall()
11 z.close()

 

 

python学习之路——基础篇(3)模块(续)