目录
ip138.com IP查询(搜索IP地址的地理位置)
您查询的IP:121.0.29.231
首页 后端开发 Python教程 python中正则表达式的使用详解

python中正则表达式的使用详解

Jun 06, 2016 am 11:19 AM
python 正则表达式

从学习Python至今,发现很多时候是将Python作为一种工具。特别在文本处理方面,使用起来更是游刃有余。

说到文本处理,那么正则表达式必然是一个绝好的工具,它能将一些繁杂的字符搜索或者替换以非常简洁的方式完成。

我们在处理文本的时候,或是查询抓取,或是替换.

一.查找
如果你想自己实现这样的功能模块,输入某一个ip地址,得到这个ip地址所在地区的详细信息.

然后你发现http://ip138.com 可以查出很详细的数据

但是人家没有提供api供外部调用,但是我们可以通过代码模拟查询然后对结果进行抓取.

通过查看这个相应页面的源码,我们可以发现,结果是放在三个

  • 中的

     

    代码如下:


     
         
             
         
         
             
         
         
     
             
         
         
             
     
         
         
         
             
       
     

     
         

    ip138.com IP查询(搜索IP地址的地理位置)

    您查询的IP:121.0.29.231

    • 本站主数据:浙江省杭州市 阿里巴巴
    • 参考数据一:浙江省杭州市 阿里巴巴
    • 参考数据二:浙江省杭州市 阿里巴巴
    如果您发现查询结果不详细或不正确,请使用IP数据库自助添加功能进行修正

     
           

    IP地址或者域名:
       

     

    如果你了解正则表达式你可能会写出

    正则表达式

     

    代码如下:


    (?).*?(?=)

     

    这里使用了前瞻:lookahead 后顾: lookbehind,这样的好处就是匹配的结果中就不会包含html的li标签了.

    如果你对自己写的正则表达式不是很自信的话,可以在一些在线或者本地的正则测试工具进行一些测试,以确保正确.

    接下来的工作就是如果用Python实现这样的功能,首先我们得将正则表达式表示出来:

     

    代码如下:


    r"(?).*?(?=)" 

     

     Python中字符串前面加上前导r这个字符,代表这个字符串是R aw String(原始字符串),也就是说Python字符串本身不会对字符串中的字符进行转义.这是因为正则表达式也有转义字符之说,如果双重转义的话,易读性很差.

    这样的串在Python中我们把它叫做"regular expression pattern"

    如果我们对pattern进行编译的话

     

    代码如下:


    prog = re.compile(r"(?).*?(?=)") 

     

    我们便可以得到一个正则表达式对象regular expression object,通过这个对象我们可以进行相关操作.

    比如

     

    代码如下:


    result=prog.match(string) 
    ##这个等同于 
    result=re.match(r"(?).*?(?=)",string) 
    ##但是如果这个正则需要在程序匹配多次,那么通过正则表达式对象的方式效率会更高 

     

    接下来就是查找了,假设我们的html结果已经以html的格式存放在text中,那么通过

     

    代码如下:


    result_list = re.findall(r"(?).*?(?=)",text) 

     

    便可以取得所需的结果列表.

    二.替换
    使用正则表达式进行替换非常的灵活.

    比如之前我在阅读Trac这个系统中wiki模块的源代码的时候,就发现其wiki语法的实现就是通过正则替换进行的.

    在使用替换的时候会涉及到正则表达式中的Group分组的概念.

    假设wiki语法中使用!表示转义字符即感叹号后面的功能性字符会原样输出,粗体的语法为

    写道
    '''这里显示为粗体'''
     那么有正则表达式为

     

    代码如下:


    r"(?P!?''')" 

     

      这里的?P是Python正则语法中的一部分,表示其后的group的名字为"bold"

      下面是替换时的情景,其中sub函数的第一个参数是pattern,第二个参数可以是字符串也可以是函数,如果是字符串的话,那么就是将目标匹配的结果替换成指定的结果,而如果是函数,那么函数会接受一个match object的参数,并返回替换后的字符串,第三个参数便是源字符串.

     

    代码如下:


    result = re.sub(r"(?P!?''')", replace, line) 

     

    每当匹配到一个三单引号,replace函数便运行一次,可能这时候需要一个全局变量记录当前的三单引号是开还是闭,以便添加相应的标记.

    在实际的trac wiki的实现的时候,便是这样通过一些标记变量,来记录某些语法标记的开闭,以决定replace函数的运行结果.

    --------------------

    示例

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

    代码

     

    代码如下:


    # -*- 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

     

  • 本站声明
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热AI工具

    Undresser.AI Undress

    Undresser.AI Undress

    人工智能驱动的应用程序,用于创建逼真的裸体照片

    AI Clothes Remover

    AI Clothes Remover

    用于从照片中去除衣服的在线人工智能工具。

    Undress AI Tool

    Undress AI Tool

    免费脱衣服图片

    Clothoff.io

    Clothoff.io

    AI脱衣机

    AI Hentai Generator

    AI Hentai Generator

    免费生成ai无尽的。

    热门文章

    R.E.P.O.能量晶体解释及其做什么(黄色晶体)
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.最佳图形设置
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌
    R.E.P.O.如果您听不到任何人,如何修复音频
    3 周前 By 尊渡假赌尊渡假赌尊渡假赌

    热工具

    记事本++7.3.1

    记事本++7.3.1

    好用且免费的代码编辑器

    SublimeText3汉化版

    SublimeText3汉化版

    中文版,非常好用

    禅工作室 13.0.1

    禅工作室 13.0.1

    功能强大的PHP集成开发环境

    Dreamweaver CS6

    Dreamweaver CS6

    视觉化网页开发工具

    SublimeText3 Mac版

    SublimeText3 Mac版

    神级代码编辑软件(SublimeText3)

    手机XML转PDF,转换速度快吗? 手机XML转PDF,转换速度快吗? Apr 02, 2025 pm 10:09 PM

    手机XML转PDF的速度取决于以下因素:XML结构的复杂性手机硬件配置转换方法(库、算法)代码质量优化手段(选择高效库、优化算法、缓存数据、利用多线程)总体而言,没有绝对的答案,需要根据具体情况进行优化。

    怎么在手机上把XML文件转换为PDF? 怎么在手机上把XML文件转换为PDF? Apr 02, 2025 pm 10:12 PM

    不可能直接在手机上用单一应用完成 XML 到 PDF 的转换。需要使用云端服务,通过两步走的方式实现:1. 在云端转换 XML 为 PDF,2. 在手机端访问或下载转换后的 PDF 文件。

    C语言 sum 的作用是什么? C语言 sum 的作用是什么? Apr 03, 2025 pm 02:21 PM

    C语言中没有内置求和函数,需自行编写。可通过遍历数组并累加元素实现求和:循环版本:使用for循环和数组长度计算求和。指针版本:使用指针指向数组元素,通过自增指针遍历高效求和。动态分配数组版本:动态分配数组并自行管理内存,确保释放已分配内存以防止内存泄漏。

    手机上如何将XML转换成PDF? 手机上如何将XML转换成PDF? Apr 02, 2025 pm 10:18 PM

    直接在手机上将XML转换为PDF并不容易,但可以借助云端服务实现。推荐使用轻量级手机App上传XML文件并接收生成的PDF,配合云端API进行转换。云端API使用无服务器计算服务,选择合适的平台至关重要。处理XML解析和PDF生成时需要考虑复杂性、错误处理、安全性和优化策略。整个过程需要前端App与后端API协同工作,需要对多种技术有所了解。

    xml怎么转换成图片 xml怎么转换成图片 Apr 03, 2025 am 07:39 AM

    可以将 XML 转换为图像,方法是使用 XSLT 转换器或图像库。XSLT 转换器:使用 XSLT 处理器和样式表,将 XML 转换为图像。图像库:使用 PIL 或 ImageMagick 等库,从 XML 数据创建图像,例如绘制形状和文本。

    如何在手机上高质量地将XML转换成PDF? 如何在手机上高质量地将XML转换成PDF? Apr 02, 2025 pm 09:48 PM

    在手机上高质量地将XML转换成PDF需要:使用无服务器计算平台在云端解析XML并生成PDF。选择高效的XML解析器和PDF生成库。正确处理错误。充分利用云端计算能力,避免在手机上进行繁重任务。根据需求调整复杂度,包括处理复杂的XML结构、生成多页PDF和添加图片。打印日志信息以帮助调试。优化性能,选择高效的解析器和PDF库,并可能使用异步编程或预处理XML数据。确保良好的代码质量和可维护性。

    如何在安卓手机上将XML转换成PDF? 如何在安卓手机上将XML转换成PDF? Apr 02, 2025 pm 09:51 PM

    直接在安卓手机上将 XML 转换为 PDF 无法通过自带功能实现。需要通过以下步骤曲线救国:将 XML 数据转换为 PDF 生成器识别的格式(如文本或 HTML);使用 HTML 生成库(如 Flying Saucer)将 HTML 转换为 PDF。

    xml格式怎么验证 xml格式怎么验证 Apr 02, 2025 pm 10:00 PM

    XML 格式验证涉及检查其结构和对 DTD 或 Schema 的遵循情况。需要使用 XML 解析器,例如 ElementTree(基本语法检查)或 lxml(更强大的验证,支持 XSD)。验证过程包括解析 XML 文件,加载 XSD Schema 并执行 assertValid 方法,以在检测到错误时抛出异常。验证 XML 格式也需要处理各种异常和深入了解 XSD Schema 语言。

    See all articles