在做项目的过程中,有时候需要再一个几万行的代码里找到某个信号,并且把它拷贝出来用。信号的定义格式是相同的,但是编号不相同,如下图所示。按道理说可以利用vim的查找功能一个个找,然后一个个地手工拷贝。如果电路有修改和迭代,查找+拷贝的方式太费时费力了,所以想到用python来处理这种有规律的、重复性的工作。

re.compile()

用正则表达式可以匹配到我想找出的信号,使用正则表达式匹配之前将re模块导入。

import re

re.compile()函数用于编译正则表达式,生成一个Pattern对象,供其他函数使用。re.compile的语法格式如下:

re.compile(pattren[, flag])

其中pattern为一个字符串形式的正则表达式;flag是可选的,用于设置匹配模式。常见的几种匹配有:

re.compile(r'\d+')            // 用于匹配数字
re.compile(r'[a-z]+')        // 用于小写字母
re.compile(r'[A-Z]+')        // 用于大写字母
……
re.compile(r'a.b')            // 符号“.”用来匹配除了换行符以外的任意字符
re.compile(r'a*b')            // 符号“*”前面的字符出现0次或以上(即以后面的字符为准)
re.compile(r'a.*b')           // 符号“.*”贪婪匹配:以a为开始以b为结束的所有内容
re.compile(r'a.*?b')          // 符号“.*?”非贪婪匹配:只要遇到以a为开始以b为结束就匹配
re.compile(r'a.*?(?=b)')     // 与上一条相同,区别在于:匹配结果不包括b
……
匹配规则不是Python特有的,更多匹配方式可见正则表达式的匹配规则
注意转义字符的匹配

转义字符是指在字母前加上反斜杠来表示的一些不能显示的ASCII字符,最常见换行符\n。文本中很可能出现类似的用转义字符表示的特定字符,举个例子:not important string... N_XI_pix_db0\<1\>\/XI_pix_even\/XI_dvs ...omit these words
如果要在文本中匹配带有转义字符的字符串N_XI_pix_db0\<1\>\/XI_pix_even\/XI_dvs,反斜杠自身也是待匹配字符,匹配的pattern可以用两种方式表示:
1.每个特殊字符前都加上反斜杠——N_XI_pix_db0\\\<1\\\>\\\/XI_pix_even\\\/XI_dvs
2.每个特殊字符都用中括号括起来——N_XI_pix_db0[\][<]1[\][>][\][/]XI_pix_even[\][/]XI_dvs

findall

与re.compile()配合使用发函数或方法有re.match()、re.search()、re.findall()、re.sub()。其区别如下:

str = `not important string... N_XI_pix_db0\<1\>\/XI_pix_even\/XI_dvs ...omit these words`
pattern = re.compile(r'N_XI_pix_db0\\\<1\\\>\\\/XI_pix_even\\\/XI_dvs')re_object = pattern.match(str)     // 从字符串的起始位置匹配,如果起始位置的字符串匹配不成功则返回"None"
re_object = pattern.search(str)        // 匹配整个字符串,并返回第一个匹配成功的项,否则返回"None"
result = re_object.group()         // 返回一个包含所有匹配的子字符串的元组result = pattern.findall(str)     // 找到所有匹配的子项并返回一个列表,如果没有匹配项则返回空列表
result = pattern.sub('replacement', str) // 用replacement替换所有的匹配项
  • 注意:上述match与search方法返回的如下图所示的正则匹配的对象,而不是匹配的字符串!若要返回匹配的内容,还要用group()方法。

    我选择了findall,满足匹配的项很多,只需要保留一个,想着用pattern.findall(str)[0]返回首个匹配项。但是,假设一个匹配项都没有,则会返回空列表,也就是不存在首项[0],因此这样写会报错。

python script

由于我要找的信号有很多个,我采用的方法是先把待匹配的所有信号放在一个字符串列表中,通过循环再逐个访问和匹配。这样做会把文本遍历很多遍,用findall方法会花费很长的时间去匹配。后续发现用search方法也能满足我的需求,因为search返回就是单个匹配项。两种方式的结果完全相同,而且search方法快了很多!

findall script
import resig_list = []
pattern_list = ['str1','str2','str3',...,'strN']with open('/path/netlist','r') as f_in:rcc_file = f_in.read();for i in range(len(rcc_file)):pattern = re.compile(pattern_list[i])sig_org = pattern.findall(rcc_file)if(len(sig_org) == 0):print(pattern_list[i], 'is not found!')else:sig_recover = sig_org[0].replace('\\','')sig_probe = 'special string' + sig_recoversig_list.append(sig_probe)sig_write = '\n'.join(sig_list)with open('/path/probe','w') as f_out:f_out.write(sig_write)print('Singal collection is done.')
  • replace方法是为了将转义字符的反斜杠去掉,使N_XI_pix_db0\<1\>\/XI_pix_even\/XI_dvs恢复成N_XI_pix_db0<1>/XI_pix_even/XI_dvs
  • 符号+将完成固定字符与找到的匹配项拼接起来,生成信号探测的tcl脚本
  • append方法在原列表sig_list的末尾位置添加新的匹配项
  • join方法在原列表中的每个字符串末尾加一个换行符,方便后续按行写入文件
  • 推荐用with open() as f的方式操作文件,确保文件的正确关闭
search script
import resig_list = []
pattern_list = ['str1','str2','str3',...,'strN']with open('/path/netlist','r') as f_in:rcc_file = f_in.read();for i in range(len(rcc_file)):pattern = re.compile(pattern_list[i])sig_org = pattern.search(rcc_file)if sig_org :sig_string = sig_org.group()sig_recover = sig_org[0].replace('\\','')sig_probe = 'special string' + sig_recoversig_list.append(sig_probe)else:print(pattern_list[i], 'is not found!')sig_write = '\n'.join(sig_list)with open('/path/probe','w') as f_out:f_out.write(sig_write)print('Singal collection is done.')
  • 此处判断是否找到对应的信号时,是否可以用以下程序中的if(sig_org == '')?答案是否定的。因为如果某个信号不存在,也就是匹配不成功,返回的是None,而python中的''表示空字符串;下面的程序进入else分支,如果用sig_org.group()方法返回元组内容,程序报错并提示'NoneType' object has no attribute 'group'
  • None是一种特殊的常量,其类型为NoneType
     // wrong codeif (sig_org == ''):print(pattern_list[i], 'is not found!')else:sig_string = sig_org.group()sig_recover = sig_org[0].replace('\\','')sig_probe = 'special string' + sig_recoversig_list.append(sig_probe)

reference

菜鸟教程python link
Python find all详解 link

Python学习之re.compile与findall相关推荐

  1. Python:利用原生函数count或正则表达式compile、findall、finditer实现匹配统计(包括模糊匹配的贪婪匹配、懒惰匹配)

    Python:利用原生函数count或正则表达式compile.findall.finditer实现匹配统计(包括模糊匹配的贪婪匹配.懒惰匹配) 目录 利用原生函数count或正则表达式compile ...

  2. Python函数封装:利用正则表达式compile、findall对多组关键词进行模糊查询并返回统计个数,findall截取两个指定符号之间的内容

    Python函数封装:利用正则表达式compile.findall对多组关键词进行模糊查询并返回统计个数,findall截取两个指定符号之间的内容 目录 利用正则表达式compile.findall对 ...

  3. Python学习系列(六)(模块)

    Python学习系列(六)(模块) Python学习系列(五)(文件操作及其字典) 一,模块的基本介绍 1,import引入其他标准模块 标准库:Python标准安装包里的模块. 引入模块的几种方式: ...

  4. 【Python教程】 re 模块中findall() 函数返回值展现方式的用法详解

    findall 函数: 在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表. 注意: match 和 search 是匹配一次 findall 匹配所有,mat ...

  5. Python学习教程(Python学习路线):第12天—正则表达式

    Python学习教程(Python学习路线):正则表达式相关知识 在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要,正则表达式就是用于描述这些规则的工具,换句话说正则表达式是 ...

  6. Python学习笔记:Day 10 用户注册和登陆

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  7. python正则匹配日期2019-03-11_都2019年了,正则表达式为啥还是这么难?这里的Python学习教程教你搞定!...

    都9102年了,你还觉得正则表达式很难?难,确实是还难啊! 这里南瓜跟大家总结的最新Python学习教程,教你搞定它! 正则表达式语法 字符与字符类 特殊字符: .^$?+*{}| 以上特殊字符要想使 ...

  8. [转载] python学习笔记

    参考链接: Python | a += b并不总是a = a + b 官网http://www.python.org/ 官网library  http://docs.python.org/librar ...

  9. python 学习总结----正则表达式

    python 学习总结----正则表达式 正则表达式应用场景- 特定规律字符串的查找,切割,替换 - 邮箱格式:URl,IP地址等的校验 - 爬虫项目中,特定内容的提取使用原则- 只要使用字符串等函数 ...

最新文章

  1. CCF-CSP 201703-2 试题名称: 学生排队(满分代码)
  2. Spring MVC快速入门
  3. python Logging日志记录模块详解
  4. setlenient_Java日历setLenient()方法与示例
  5. 安装faac编译问题
  6. 开源工具kettle中Job流程的理解
  7. mapreduce on yarn简单内存分配解释
  8. mysql 查询 一天的时间_MySQL怎么查询每天打卡的最早时间和最晚时间?
  9. ImportError: No module named bs4
  10. 《初识Scratch》教学设计
  11. 贪吃蛇速度变快c语言程序,简单贪吃蛇C语言程序
  12. Linux 下完整安装ffmpeg(包括各种解码器)
  13. 饥荒联机版你的服务器无响应,饥荒联机版为什么每次创建世界都会无响应 | 手游网游页游攻略大全...
  14. 高等数学张宇18讲 第二讲 极限与连续
  15. Idea安装MarkDown插件
  16. Speedoffice(word)文档如何设置分栏
  17. 沃尔夫冈·阿玛多伊斯·莫扎特
  18. html、css --苏宁官网静态界面
  19. html5 application cache 空间限制,HTML5离线存储之Application Cache
  20. 贝叶斯统计推断(一)

热门文章

  1. 计算机基础课程高质量公开课程整理(长期整理)
  2. 《OpenDRIVE1.6规格文档》2
  3. 模拟键盘鼠标事件有两种方法
  4. 豆瓣高分推荐:提升管理力,怎么能不看这6本书
  5. !!return——执行了return语句,后面的语句将不会执行!!
  6. 电子烟中测电阻注意事项
  7. python京东抢购手机攻略_Python实现自动上京东抢手机
  8. Android对应的版本号
  9. loaderrunner11.00安装与破解
  10. LoadRunner9.1下载与破解