Perl正则负前瞻失效:如何精准捕获NWChem输出指定区块内容
NWChem输出文件正则匹配问题解决
问题场景
需要解析NWChem输出文件,文件中存在约10个类似如下的区块:
General Information ------------------- SCF calculation type: DFT Wavefunction type: closed shell. No. of atoms : 10 No. of electrons : 36 Alpha electrons : 18 Beta electrons : 18 Charge : 0 Spin multiplicity: 1 Use of symmetry is: on ; symmetry adaption is: on Maximum number of iterations: 30 AO basis - number of functions: 95 number of shells: 45 Convergence on energy requested: 1.00D-06 Convergence on density requested: 1.00D-05 Convergence on gradient requested: 5.00D-04 XC Information --------------
已将文件内容存入字符串$str,并把所有换行符替换为я,希望捕获每个区块的中间内容(即标题分隔线之后、下一个区块标题分隔线之前的部分),但原正则几乎捕获了整个文件,不符合预期。
原正则问题分析
原正则中的(.+(?!\-{2,}))采用贪婪匹配,且负前瞻的位置错误——它只检查整个匹配的末尾是否没有连续两个-,而非在匹配过程中逐字符限制,导致正则会尽可能多的匹配内容,直到文件末尾才停止。
修正后的正则及解释
将捕获组修改为((?:(?!\-{2,}).)+),完整正则如下:
my @capture = $str =~ m/General\s+Informationя \s+[-]+я ((?:(?!\-{2,}).)+) # 匹配至连续两个-出现前的所有内容 яя\s+[-]+ /xg;
关键部分解释
(?:(?!\-{2,}).):非捕获组,作用是匹配任意单个字符,但该字符之后不能出现连续两个-,这样就限制了匹配过程中不会跨过下一个区块的分隔线+:重复上述匹配逻辑,直到遇到连续两个-的位置为止/xg修饰符:x允许正则中的空白和注释,g实现全局匹配,捕获所有符合条件的区块
这个正则会精准捕获每个General Information区块的中间内容,同时允许内容中出现单个-(如示例里的AO basis - number of functions),不会过度匹配。
内容的提问来源于stack exchange,提问作者con
相关产品推荐
相关产品推荐

