tag 标签: 正则表达式

相关博文
  • 热度 5
    2024-4-4 16:56
    2104 次阅读|
    0 个评论
    TCL脚本对文本文件中的数据提取操作
    项目调试的时候会产生很多类似的文本文件,这些文本文件可以在离线的时候进行处理。比如,最近需要对log文件里的某个或某几个参数进行提取,由于单个log文件中总共只包含了49组参数数据(每组包含5种不同的参数),一开始的时候觉得只有49组,手动提取到Excel中再进行分析处理,但是当log变多了以后,就会变得很繁琐,而且效率十分低下。 为了能够及时处理并从文本文件中提取感兴趣的数据,可以使用C++、Labview等编程语言编写简单的程序进行处理。我们在实际测试中,也是C程序员来帮助编写这种简便的”function“来帮助处理这些文本log文件。 用C语言处理这类文件,有几个弊端,比如大量的function功能块,C程序员需要花费精力进行管理,另外这些function的应用时,还是需要用户手动输入若干个匹配条件才能完成完整的处理。 此时,想到之前使用的TCL脚本开发的平台,包含了对文件的处理。虽然之前关注的是文本文件到二进制文件、或者二进制数据读取再写入文本文件的操作,这涉及数据的转换或者叫重新配置。当前log文件处理,只是对文件中的数据进行提取,或者说就是简单的对字符的提取处理,应该更简单,所以打算使用该平台额外添加一个功能来完成此功能。这里记录该功能开发的过程。 首先,我们来看log文件的格式,如下所示,为log文件中的前3组参数,每组5个一样的参数,这里列出了15行。 Crystal_ID: 0 PEAK: 103.00 L-FWHM: 96.83 R-FWHM: 108.13 ENERGY RESOLUTION (%): 10.97 Crystal_ID: 1 PEAK: 121.00 L-FWHM: 114.42 R-FWHM: 127.09 ENERGY RESOLUTION (%): 10.47 Crystal_ID: 2 PEAK: 121.00 L-FWHM: 114.98 R-FWHM: 127.92 ENERGY RESOLUTION (%): 10.69 log文件保存为任意名称的文本格式文件,我们感兴趣的是每组参数中的第二个和最后一个参数,即PEAK和ENERGY RESOLUTION这两个参数,实际我们需要提取的只是他们对应的数字而已。为了用TCL脚本处理,找来之前开发的平台,如图1所示。计划将按钮”创建MIF文件“功能修改成我们所需的功能;修改后的平台GUI如图2所示。 图1:现存的创建MIF文件的TCL/TK平台 图2:将图1中的按钮简单修改后的TCL/TK开发平台 下面着手修改按钮的具体功能,其基本功能应该包含打开log文本文件,提取匹配PEAK和ENERGY的行,从匹配到的行中提取所需的数据并存入到不同的文本文件中,这里使用PK.txt和ER.txt两个文件来分别进行存取。其完整代码如下所示, set chan ##set chan set myfile1 set myfile2 =0} { ;##依次整行读取字符 ##regexp {^(\w+)\s(\d+)} $line total ##lineStart num regexp {^\w+} $line lineStart ##通过正则表达式提取字符串头 regexp {\d+} $line num1 ##通过正则表达式提取字符串中数字段,无法提取小数点,并且小数点打断了完整数据提取 regexp {\d+.*$} $line num2 ##通过正则表达式提取字符中数字,由于数据位于行尾,通过起始数字加.*与字符串结尾符$完成了完整小数的提取。 ##.t insert end "\n$total" .t insert end "\n$lineStart" .t insert end "\n$num1" .t insert end "\n$num2" if {$lineStart=="PEAK" } { puts $myfile1 $num2 .t insert end "\n哈!Peak location 找到了!" } elseif {$lineStart=="ENERGY"} { puts $myfile2 $num2 .t insert end "\n哈!Energy Resolution 找到了!" } else { .t insert end "\n哦!这个不是我想要的!" } } close $chan close $myfile1 close $myfile2 点击“文本文件数据提取”按钮,其执行结果如图3所示 图3:点击按钮后其执行结果打印在文本显示窗口,同时还是创建两个文本文件来存储提取的数据 该功能的关键点主要有这几个: 1. 将log文件内容当成字符看待,后续操作均采用的是字符和字符串的操作; 2. 打开log文件后,首先逐行读取并判断; 3. 使用到正则表达式,regexp;使用regexp首先提取行头,判断是否是PEAK或ENERGY; 4. 判断遇到PEAK或ENERGY行后,再提取改行行尾数字;(注:实际操作是逐行读取并同时进行相关提取,后续通过if语句进行判决是否是需要的数据)。 5. 遇到需要的数据后,分别存储到对应创建的文件之中; 6. 完成最终操作,关闭所有打开的文件。 总结 在进行提取的时候其实遇到了一点问题,不同脚本开发软件或者C#语言都有正则表达式的操作。经过测试,似乎TCL的正则表达式操作限制更多,或者说我使用的TCL编译器版本低的问题,导致我使用的时候遇到一些问题。 这里首先感谢网络上分享的内容,比如这个: https://blog.csdn.net/tong66666666/article/details/134981436 我遇到的问题,其实在上述代码里的注释中有提到,即在提取数字的时候,遇到小数点就被打断,即正则提取的时候,没有识别小数或者小数点的方式。代码中使用两种方式来提取每个数字,比如图3中的ENERGY,分别提取为10和10.97,这当中,10.97是完整的能谱分辨率。提取的10是因为遇到小数点后,提取动作被打断后的结果。 我们的log由于将数字存放在了每个行的行尾,所以最终能够提取到完整的10.97是使用了匹配到数字后,提取到行尾结束本次提取,这样才得到所需的完整数据。
  • 热度 22
    2017-11-10 09:23
    1321 次阅读|
    0 个评论
    (一)正则表达式: 通用的字符串表达框架; 简洁表达一组字符串的表达式; 针对字符串表达“简洁”和“特征”思想的工具; 判断某字符串的特征归属; 正则表达式在文本中的常见作用: 表达文本类型的特征(病毒); 同时查找或替换一组字符串; 匹配字符串的全部或部分; 正则表达式的使用: 编译:将符合正则表达式语法的字符串转换成正则表达式特征。 (二)正则表达式的语法 (三)正则常用的操作符 (四)正则表达式实例 (五)re库的主要功能函数 正则表达式的表示类型 (1)raw string 类型(原生字符串类型) re 库采用 raw string 类型表示正则表达式,表示为 r’text’ 。 例如:大陆地区的邮政编码 : r’ \d{5}’        国内的电话号码: r’\d{3}-\d{8}|\d{4}-\d{7}’    原生字符串类型是不包含转义符的字符串。 (2)string 类型,更加繁琐     例如 ’ \\d{5} ’                   ’\\d{3}-\\d{8}|\\d{4}-\\d{7}’ 所以当正则表达式包含转义字符时,使用 raw string 。 1、re.search(pattern,string,flags=0) 在一个字符串中搜索匹配正则表达式的第一个位置,返回 match 对象。 pattern: 正则表达式的字符串或原生字符串的表示 ; string: 带匹配字符串; flags: 正则表达式使用时的控制标记; 代码 2、re.match(pattern,string,flags=0) 从一个字符串的开始位置起匹配正则表达式,返回match对象 3、re.findall(pattern,string,flags=0) 搜索字符串,以列表类型返回全部能匹配的子串。 4、re.split(pattern,string,maxsplit=0,flags=0) 将一个字符串按照正则表达式匹配结果进行分割,返回列表类型。 maxsplit: 最大分割数,剩余部分作为最后一个元素输出。 5、re.finditer(pattern,string,flags=0) 搜索字符串,返回一个匹配结果的迭代类型,每个迭代元素是 match 对象。 6、re.sub(pattern,repl,string,count=0,flags=0) 在一个字符串中替换所有匹配正则表达式的子串,返回替换后的字符串。 Pattern: 正则表达式的字符串或原生字符串表示; Repl: 替换匹配字符串的字符串; String: 待匹配的字符串; Count: 匹配的最大替换数; (六)re库的另一种用法 (七)match对象 1、match对象的属性 2、match对象的方法 (八)re库的贪婪匹配和最小匹配 Re 库默认采用贪婪匹配,即输出匹配最长的字符串。 1、最小匹配操作符 ​ ​
  • 热度 14
    2017-7-11 10:30
    883 次阅读|
    0 个评论
    扩展的正则表达式是针对基础正则表达式的补充,它比后者多了几个重要的符号,在使用这些符号的时候,需要使用egrep命令。 ? 表示匹配前一个字符0次或1次,比如'ro?t'匹配rot或rt; + 表示匹配前一个字符1次以上,比如'ro+t'匹配rot、root等; | 通常和 () 联合使用,用于枚举一系列可替换的字符。 正则表达式和通配符,既有联系又有区别。 前者主要匹配文件内容,多用在grep命令里;后者主要匹配文件名,多用在find命令里。
  • 热度 11
    2017-7-11 10:07
    958 次阅读|
    0 个评论
    正则表达式非常常见,它是一种文本匹配工具: 正则表达式就是能用某种模式去匹配一类字符串的公式,它是由一串字符和元字符构成的字符串。 所谓元字符,就是用以阐述字符表达式的内容、转换和描述各种操作信息的字符。 ——《Linux系统命令及Shell脚本实践指南》 . (点符号)用于匹配除换行符之外的任意一个字符。 * (星符号)用于匹配前一个字符0次或任意多次: 此处的 * 和bash环境里的 * 有区别,前者是匹配前一个字符,比如ab 表示a、ab、abb、abbb……,后者表示0到无穷多个任意字符。bash环境里面的 . 和 等,又称为通配符。 正则表达式里的 .* ,才表示任意字符。 {n,m} 能够更加灵活地控制字符的重复次数: {n} 表示匹配前面的字符n次,比如'ro{2}t'; {n,} 表示匹配前面的字符n次以上(含n次),比如'ro{0}t'; {n,m} 表示匹配前面的字符n次到m次,比如'ro{0,2}t'。 ^ 用于匹配开头的字符,比如'^root'表示以root开始的行。 $ 用于匹配尾部的字符,比如'abc$'表示以abc结尾的行,'^$'则表示空行。 ',或者' '。 如果括号内使用了 ^ ,则表示取反,比如'^ '。 \ 表示转义,比如' '。 和 用于界定单词的左边界和右边界,比如'hello'用于匹配以 hello 开头的单词,而'hello'用于匹配以 hello 结尾的单词。它们的组合用于精确匹配字符串。 还有一些不常用的基础正则表达式,现用现查即可。
相关资源