python正则表达式 小例几则

news/2024/7/19 12:44:55 标签: 爬虫, python

 

会用到的语法

正则字符

释义

举例

+

前面元素至少出现一次

ab+:ab、abbbb 等

*

前面元素出现0次或多次

ab*:a、ab、abb 等

?

匹配前面的一次或0次

Ab?: A、Ab 等

^

作为开始标记

^a:abc、aaaaaa等

$

作为结束标记

c$:abc、cccc 等

\d

数字

3、4、9 等

\D

非数字

A、a、- 等

[a-z]

A到z之间的任意字母

a、p、m 等

[0-9]

0到9之间的任意数字

0、2、9 等

注意:

1. 转义字符

>>> s
'(abc)def'
>>> m = re.search("(\(.*\)).*", s)
>>> print m.group(1)
(abc)

group()用法参考

2. 重复前边的字串多次

>>> a = "kdlal123dk345"
>>> b = "kdlal123345"
>>> m = re.search("([0-9]+(dk){0,1})[0-9]+", a)
>>> m.group(1), m.group(2)
('123dk', 'dk')
>>> m = re.search("([0-9]+(dk){0,1})[0-9]+", b)
>>> m.group(1)
'12334'
>>> m.group(2)
>>> 

示例

一. 判断字符串是否是全部小写

代码

# -*- coding: cp936 -*-
import re  
s1 = 'adkkdk'
s2 = 'abc123efg'

an = re.search('^[a-z]+$', s1)
if an:
    print 's1:', an.group(), '全为小写' 
else:
    print s1, "不全是小写!"

an = re.match('[a-z]+$', s2)
if an:
    print 's2:', an.group(), '全为小写' 
else:
    print s2, "不全是小写!"

结果

 

究其因

1. 正则表达式不是python的一部分,利用时需要引用re模块

2. 匹配的形式为: re.search(正则表达式, 带匹配字串)或re.match(正则表达式, 带匹配字串)。两者区别在于后者默认以开始符(^)开始。因此,

re.search('^[a-z]+$', s1) 等价于 re.match('[a-z]+$', s2)

3. 如果匹配失败,则an = re.search('^[a-z]+$', s1)返回None

group用于把匹配结果分组

例如

import re
a = "123abc456"
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)   #123abc456,返回整体
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)   #123
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)   #abc
print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)   #456

1)正则表达式中的三组括号把匹配结果分成三组

  group() 同group(0)就是匹配正则表达式整体结果

  group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分。

2)没有匹配成功的,re.search()返回None

3)当然郑则表达式中没有括号,group(1)肯定不对了。

二.  首字母缩写词扩充

具体示例

FEMA   Federal Emergency Management Agency
IRA    Irish Republican Army
DUP    Democratic Unionist Party
FDA Food and Drug Administration OLC Office of Legal Counsel

分析

缩写词  FEMA
分解为  F*** E*** M*** A***
规律    大写字母 + 小写(大于等于1个)+ 空格

参考代码

import re
def expand_abbr(sen, abbr):
    lenabbr = len(abbr)
    ma = '' 
    for i in range(0, lenabbr):
        ma += abbr[i] + "[a-z]+" + ' '
    print 'ma:', ma
    ma = ma.strip(' ')
    p = re.search(ma, sen)
    if p:
        return p.group()
    else:
        return ''

print expand_abbr("Welcome to Algriculture Bank China", 'ABC')

结果

问题

上面代码对于例子中的前3个是正确的,但是后面的两个就错了,因为大写字母开头的词语之间还夹杂着小写字母词

规律 

大写字母 + 小写(大于等于1个)+ 空格 + [小写+空格](0次或1次)

参考代码

import re
def expand_abbr(sen, abbr):
    lenabbr = len(abbr)
    ma = '' 
    for i in range(0, lenabbr-1):
        ma += abbr[i] + "[a-z]+" + ' ' + '([a-z]+ )?'
    ma += abbr[lenabbr-1] + "[a-z]+"
    print 'ma:', ma
    ma = ma.strip(' ')
    p = re.search(ma, sen)
    if p:
        return p.group()
    else:
        return ''

print expand_abbr("Welcome to Algriculture Bank of China", 'ABC')

技巧

中间的 小写字母集合+一个空格,看成一个整体,就加个括号。要么同时有,要么同时没有,这样需要用到?,匹配前方的整体。

三. 去掉数字中的逗号

具体示例

在处理自然语言时123,000,000如果以标点符号分割,就会出现问题,好好的一个数字就被逗号肢解了,因此可以先下手把数字处理干净(逗号去掉)。

分析

数字中经常是3个数字一组,之后跟一个逗号,因此规律为:***,***,***

正则式

[a-z]+,[a-z]?

参考代码3-1

import re

sen = "abc,123,456,789,mnp"
p = re.compile("\d+,\d+?")

for com in p.finditer(sen):
    mm = com.group()
    print "hi:", mm
    print "sen_before:", sen
    sen = sen.replace(mm, mm.replace(",", ""))
    print "sen_back:", sen, '\n'

结果

技巧

使用函数finditer(string[, pos[, endpos]]) | re.finditer(pattern, string[, flags]):

搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。      

参考代码3-2

sen = "abc,123,456,789,mnp"
while 1:
    mm = re.search("\d,\d", sen)
    if mm:
        mm = mm.group()
        sen = sen.replace(mm, mm.replace(",", ""))
        print sen
    else:
        break

结果

延伸

这样的程序针对具体问题,即数字3位一组,如果数字混杂与字母间,干掉数字间的逗号,即把“abc,123,4,789,mnp”转化为“abc,1234789,mnp”

思路

更具体的是找正则式“数字,数字找到后用去掉逗号的替换

参考代码3-3

sen = "abc,123,4,789,mnp"
while 1:
    mm = re.search("\d,\d", sen)
    if mm:
        mm = mm.group()
        sen = sen.replace(mm, mm.replace(",", ""))
        print sen
    else:
        break
print sen

结果

四. 中文处理之年份转换(例如:一九四九年--->1949年)

中文处理涉及到编码问题。例如下边的程序识别年份(****年)时

# -*- coding: cp936 -*-
import re
m0 =  "在一九四九年新中国成立"
m1 =  "比一九九零年低百分之五点二"
m2 =  '人一九九六年击败俄军,取得实质独立'

def fuc(m):
    a = re.findall("[零|一|二|三|四|五|六|七|八|九]+年", m)
    if a:
        for key in a:
            print key
    else:
        print "NULL"

fuc(m0)
fuc(m1)
fuc(m2)

运行结果

可以看出第二个、第三个都出现了错误。

改进——准化成unicode识别

# -*- coding: cp936 -*-
import re
m0 =  "在一九四九年新中国成立"
m1 =  "比一九九零年低百分之五点二"
m2 = '人一九九六年击败俄军,取得实质独立'

def fuc(m):
    m = m.decode('cp936')
    a = re.findall(u"[\u96f6|\u4e00|\u4e8c|\u4e09|\u56db|\u4e94|\u516d|\u4e03|\u516b|\u4e5d]+\u5e74", m)

    if a:
        for key in a:
            print key
    else:
        print "NULL"

fuc(m0)
fuc(m1)
fuc(m2)

结果

识别出来可以通过替换方式,把汉字替换成数字。

参考

numHash = {}
numHash[''.decode('utf-8')] = '0'
numHash[''.decode('utf-8')] = '1'
numHash[''.decode('utf-8')] = '2'
numHash[''.decode('utf-8')] = '3'
numHash[''.decode('utf-8')] = '4'
numHash[''.decode('utf-8')] = '5'
numHash[''.decode('utf-8')] = '6'
numHash[''.decode('utf-8')] = '7'
numHash[''.decode('utf-8')] = '8'
numHash[''.decode('utf-8')] = '9'

def change2num(words):
    print "words:",words
    newword = ''
    for key in words:
        print key
        if key in numHash:
            newword += numHash[key]
        else:
            newword += key
    return newword

def Chi2Num(line):
    a = re.findall(u"[\u96f6|\u4e00|\u4e8c|\u4e09|\u56db|\u4e94|\u516d|\u4e03|\u516b|\u4e5d]+\u5e74", line)
    if a:
        print "------"
        print line
        for words in a:
            newwords = change2num(words)
            print words
            print newwords
            line = line.replace(words, newwords)
    return line
View Code

 

四. 推荐

Python正则表达式指南

 

 


http://www.niftyadmin.cn/n/1001709.html

相关文章

小鸡手柄和劲玩X3蓝牙手柄对比

这个时代变化真快。 智能手机的性能越来越强,现在已经具有2GB(甚至3GB)的内存和几十GB的闪存存储空间了。因此,在手机上通过模拟器来玩那些小时候家用游戏机上的游戏早已不是难事了。Android由于其开放的体系,游…

基于Salt Event系统构建Master端returner

前置阅读环境说明开工前置配置编写returner测试SaltStack 的 returner 是由minion端主动连接returner完成执行结果的存储, 在部分场景下并不能满足需求. 由于Salt底层已经构建了一套 Event系统, 所有的操作均会产生event. 因此基于Salt Event系统构建Master端returner成为一种可…

Android软件开发之盘点所有Dialog对话框大合集(一)

对话框大合集雨松MOMO原创文章如转载,请注明:转载自雨松MOMO的博客原文地址:http://blog.csdn.net/xys289187120/article/details/6601613雨松MOMO带大家盘点Android 中的对话框今天我用自己写的一个Demo 和大家详细介绍一个Android中的对话框的使用技巧…

四.Java 集合

2019独角兽企业重金招聘Python工程师标准>>> 4.1 声明为接口类 List listnew ArrayList(); 4.2 fast-fail机制 [java] view plaincopy for (Iterator<Integer> iter list.iterator(); iter.hasNext();) { int i iter.next(); if (i 3) …

该公众号暂时无法提供服务请稍后再试

关键字&#xff1a;该公众号暂时无法提供服务&#xff0c;请稍后再试 微信公众平台 原文&#xff1a;http://www.cnblogs.com/txw1958/p/weixin-suspend-service-solution.html 在用户向公众号发消息&#xff0c;或点击自定义菜单时&#xff0c;开发者一般会根据业务需要&…

把VBScript的函数迁移到C#.NET

原文:把VBScript的函数迁移到C#.NETVBScript 5.6 FunctionsC# codeAbsSystem.Math.AbsArrayNew Object() { }Asc, AscB, AscWMicrosoft.VisualBasic.Strings.AscAtnSystem.Math.AtanCBoolSystem.Convert.ToBooleanCByteSystem.Convert.ToByteCCurSystem.Convert.ToDecimalCDate…

javascript事件详细说明

javascript事件列表解说javascript事件列表解说事件 浏览器支持 解说一般事件 onclick IE3、N2 鼠标点击时触发此事件ondblclick IE4、N4 鼠标双击时触发此事件onmousedown IE4、N4 按下鼠标时触发此事件onmouseup IE4、N4 鼠标按下后松开鼠标时触发此事件onmouseover IE3、N2 …

最实用的10个重构小技巧排行榜

LZ最近一直在研究虚拟机源码&#xff0c;可惜目前还只是稍微有一点点头绪&#xff0c;无法与各位分享&#xff0c;庞大的JAVA虚拟机源码果然不是一朝一夕能搞定的&#xff0c;LZ汗颜。 本次我们抛开JAVA虚拟机源码这些相对底层的东西&#xff0c;LZ来与各位探讨一下几个代码重构…