如何使用Python从复杂的字符串中提取,比较和转换数据?

时间:2015-07-26 20:33:00

标签: python regex escaping

我有一系列Maya MEL命令,我试图用Python读取,比较和转换。我能够阅读这些内容,但是我无法提取所需的数据。每个命令行都包含一个标识符和一系列有序变量,通常只有3个但始终与同一标识符的另一行的变量数对称。

例如,我的文件可能包含以下内容:

// Default Lip Positions - 15_0504
setAttr("Lower_Lips.translate", 1.670481893, 10.29264716, 0.0005245589302)  ;
setAttr("Lower_Lips.rotate", 80.13419306, -90, 0);
setAttr("Lower_Lips.scale", 1, 1, 1) ;
setAttr("Lower_Lips.cv[12]", -0.5607159408, -0.815908366, 10.34516376) ;
setAttr("Lower_Lips.cv[11]", -0.5142785558, -0.9430959629, 10.29982363) ;   
// Default 15_0726
setAttr("Lower_Lips.translate", 1.670481893, 10.29264716, 0.0005245589302);
setAttr("Lower_Lips.rotate", 80.13419306, -90, 0) ;
setAttr("Lower_Lips.cv[11]", -0.4987127378, -0.9397891962, 10.31868927);
setAttr("Lower_Lips.scale", 1, 1, 1) ;
setAttr("Lower_Lips.cv[12]", -0.5437445653, -0.815908366, 10.36395894) ;

我需要将标识符(双引号之间的文本)和相关值提取到数据结构中。我还需要忽略评论或空行。所以,第一个元组就像是:

('Lower_Lips.translate', '1.670481893','10.29264716','0.0005245589302')

稍后,更复杂的命令行的元组将是:

('Lower_Lips.cv[12]', '-0.5607159408', '-0.815908366', '10.34516376')

然后我可以查找重复的标识符并对它们的两组值执行一些操作,比如查找差异。我试图用Regex做到这一点,并确定标识符的模式将是这样的:

re.compile('.*"([^"]*)".*')

1 个答案:

答案 0 :(得分:0)

您可以尝试使用f.read()读取整个文件,然后在内容上应用此正则表达式代码:

import re
p = re.compile(r'^setAttr\("([^"]*)",\s+(\S*),\s+(\S*),\s+(\S*)\)\s*;', re.MULTILINE)
test_str = "// Default Lip Positions - 15_0504\nsetAttr(\"Lower_Lips.translate\", 1.670481893, 10.29264716, 0.0005245589302)  ;\nsetAttr(\"Lower_Lips.rotate\", 80.13419306, -90, 0);\nsetAttr(\"Lower_Lips.scale\", 1, 1, 1) ;\nsetAttr(\"Lower_Lips.cv[12]\", -0.5607159408, -0.815908366, 10.34516376) ;\nsetAttr(\"Lower_Lips.cv[11]\", -0.5142785558, -0.9430959629, 10.29982363) ;   \n// Default 15_0726\nsetAttr(\"Lower_Lips.translate\", 1.670481893, 10.29264716, 0.0005245589302);\nsetAttr(\"Lower_Lips.rotate\", 80.13419306, -90, 0) ;\nsetAttr(\"Lower_Lips.cv[11]\", -0.4987127378, -0.9397891962, 10.31868927);\nsetAttr(\"Lower_Lips.scale\", 1, 1, 1) ;\nsetAttr(\"Lower_Lips.cv[12]\", -0.5437445653, -0.815908366, 10.36395894) ;"
print(re.findall(p, test_str))

正则表达式

^setAttr\("([^"]*)",\s+(\S*),\s+(\S*),\s+(\S*)\)\s*;

只检查每一行,并从每个符合该模式的数据中提取必要的数据。