Python 正则表达式
分类:技术
先说一个比较囧的事情:在写虾米音乐试听下载器的时候遇到一个问题,因为保存的文件都是用音乐的标题命名的,所以碰到一些诸如「対峙/out border」等含有非法字符(哼哼,说的就是你 →_→ Windows)的标题的时候,就会保存失败。于是我想起了迅雷的解决方法:把所有的非法字符替换成下划线。
于是就引入了正则表达式的使用。一番搜索囫囵吞枣后,我写下了这样的函数:
def sanitize_filename(filename):
return re.sub('[\/:*?<>|]', '_', filename)
最近意识到了这个函数里的好多问题:
- Python 和 Shell 不同,无论单引号还是双引号,反斜杠都是转义符。走狗屎运的是,Python 对于没意义的转义
\/
的处理是保持原样。 - 即便如此,
sanitize_filename('\\/:*?<>|')
依旧返回\_______
而不是全部都是下划线。
于是感觉得正正经经看看文档了。
Raw strings
看了文档后才意识到,Python 正则表达式模块的转义是独立的。例如匹配一个反斜杠字符需要将参数写成:'\\\\'
:
- Python 将字符串转义:
\\\\
被转义为\\
re
模块获得传入的\\
将其解释为正则表达式,按照正则表达式的转义规则将其转义为\
如此麻烦的前提下,Raw String 就大有作为了,顾名思义就是(除了结尾的反斜杠)不会被转义的字符串。于是匹配一个反斜杠字符就可以写作 r'\\'
。
所以上面的 sanitize_filename
改成了:
def sanitize_filename(filename):
return re.sub(r'[\\/:*?<>|]', '_', filename)
Regex 和 Match
于是正经看看 re
模块吧~以下为流水帐,供急性子观看。
Python 的正则表达式模块 re
中主要的对象其实是这俩:
- 正则表达式
RegexObject
- 匹配
MatchObject
RegexObject
是正则表达式对象,所有 match
sub
之类的操作都归它所有。由 re.compile(pattern, flag)
生成。
>>> email_pattern = re.compile(r'\w+@\w+\.\w+')
>>> email_pattern.findall('My email is abc@def.com and his is user@example.com')
['abc@def.com', 'user@example.com']
其中的方法:
search
从任意字符开始匹配,返回MatchObject
或者None
match
从第一个字符开始匹配,返回MatchObject
或者None
split
返回由匹配分割的 Listfindall
返回所有匹配的 Listfinditr
返回MatchObject
的迭代器sub
返回替换后的字符串subn
返回(替换后的字符串, 替换次数)
re
模块里提供的函数如 re.sub
re.match
re.findall
实际上都可以认为是一种省去直接创建正则表达式对象的捷径。而由于 RegexObject
对象本身可以反复使用,这也是它相对于这些捷径函数的优势所在。
MatchObject
则是匹配对象,表示一次正则表达式匹配的结果。由 RegexObject
的一些方法返回。匹配对象永远是 True
的,另外还有一大堆用来取得正则表达式中分组(group)相关信息的方法。
>>> for m in re.finditer(r'(\w+)@\w+\.\w+', 'My email is abc@def.com and his is user@example.com'):
... print '%d-%d %s %s' % (m.start(0), m.end(0), m.group(1), m.group(0))
...
12-23 abc abc@def.com
35-51 user user@example.com
你的博客很漂亮
赏心悦目啊~!
WordPress?
当然,文章写得也很好,嘿嘿
@唐风
多谢哈~是 Typecho.