||
以前用VBA和Python解析过配方文本, 现在我试试用Perl来解析.
配方文本一般有几种常见形式:
1)完全是归一化的, 所有成本加起来为100或100%.这种最好解析,不用折算.
常见的有几种不同的写法,如
"TEST01 13.6%LiPF6,33.56%EMC,16.78%DEC,33.56%PC,1%LiTFSI,1.5%PS";
或 "TEST02 LIPF6:12.5%,EMC:37.5%,DEC:30%,PC:17%,LiFSI: 2.0%,VC:1.0%";
2) 溶剂采用质量比例;其它成分用百分数的, 按最终配方的含量处理. 与上面类似,百分数也有两种表示方式,如
"TEST03 EC:EMC:DEC:PC=1:2:1:1, 8.0%LIPF6,1.5%VC,2.5%PS" 或者是
"TEST04 EC:EMC:DEC:PC=1:2:1:1, LIPF6:10%,LiTFSI:3.5%,PS:1.5%"
3)其它形式, 比如锂盐用摩尔数来表示的, 溶剂用体积比来表示的. 添加剂是按(锂盐+溶剂=100%)再外加的, 添加剂按溶剂含量的多少来计算的. 由于处理的方法类似,只是代码中要体现这种逻辑,这里就没有去尝试.
以上4种模式,我分别用mode1 ~ mode4 来代表. mode3~4有点不同的是, 需要先算出其它成分的百分数,再按比例计算各溶剂的百分数. 所有的成分名称存放到一个数组, 所有的含量存放到另一个数组.
解析的工作不多,先构建代表添加剂或溶剂的正则表达式,再按不同的模式来拼接成一个完整的表达式.
这种组合形成样式的好处就是,方便拼接各种不同的样式. m1pat表示 mode1的正则表达式样式(pattern).
为了简化正则表达式的搜索式,在提取了型号($code)之后,我把字串的空格都删除了,以方便设计正则样式.
另外,这里还利用了Perl对命名捕获的支持. 后面提取信息时方便一点.
所有的正则表达式都很抽象,在RegexBuddy中调试好再使用, 非常必要. Perl虽然对正则表达式支持很好,但结果不太直观。还是专业的RegexBuddy好使。
主要的代码部分很短,就这一部分,
@formuArray是我从指定的文件中读出来的配方文本的数组. 逐个文本的解析用ParseFormuText函数处理.
解析函数返回四个结果,它们组成一个数组返回,其中成分名称数组@cmpName, 含量数组@cmpWt是用引用形式返回的(前面加了\). 函数中根据文本的不同模式, 用不同的代码块来解析,解析完成就直接退出函数返回结果了.样子如下
为了方便对配方进行分析,还分类别计算了配方中添加剂、锂盐和溶剂的总和各占多少.(即CheckWtByCategory函数).这个怎么检查的呢? 手工为每个种类设计了一组成分清单, 逐一进行比对,这种方法比较简单粗暴,但可以用.
整体感觉下来,Perl代码写起来与之前学了一点的PowerShell有点相似。似乎Perl更灵活一点。
完整的代码如下: Perl parser for formula.rar
执行的结果就是在同一目录下生成多个文件.文件的个数取决于wbFormu.xls这个文件中保存的配方文本数目, 示例就是就4个,每种模式一个.
还有一个源码转来的PDF文件, 如下little_Perl_prog 2021-5-12.pdf
赠送手工整理的Perl资料一本,特别声明不是我翻译的.《Modern Perl》.pdf
为了读取和写入Excel文件(早期的xls), perl之外,还需要安装几个模块
Spreadsheet::ParseExcel;
Spreadsheet::ParseExcel::FmtUnicode;
Spreadsheet::WriteExcel;
需要安装什么模块,在命令行下用cpanm XXX就好了.
代码是用perltidy处理的,需要的也可以在cpan上安装: cpanm Perl::Tidy
---------------------
新手上路, 以上主要是写给自己备忘的.
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2024-12-26 19:06
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社