Python多行正则表达式+多个条目一次读取一个文件

||
//Last modified: Sat, Apr 16, 2011 09:55:04 AM
//Codeset: ISO-8859-1
fileInfo \"version\" \"20x64\";
createNode newnode -n \"a_SET\";
    addAttr -ci true -k true -sn \"connections\" -ln \"connections\" -dt \"string\";
    setAttr -l on -k off \".tx\";
    setAttr -l on -k off \".ty\";
    setAttr -l on -k off \".sz\";
    setAttr -l on -k on \".test1\" -type \"string\" \"blabla\";
    setAttr -l on -k on \".test2\" -type \"string\" \"blablabla\";
createNode newnode -n \"b_SET\";
    addAttr -ci true -k true -sn \"connections\" -ln \"connections\" -dt \"string\";
    setAttr -l on -k off \".tx\";
    setAttr -l on -k off \".ty\";
    setAttr -l on -k off \".sz\";
    setAttr -l on -k on \".test1\" -type \"string\" \"hmm\";
    setAttr -l on -k on \".test2\" -type \"string\" \"ehmehm\";
在Python中: 我需要读取实例\“ a_SET \”和\“ b_SET \”的新节点名称及其对应的属性值,因此{\“ a_SET \”:{\“ test1 \”:\“ blabla \”,\“ test2 \ “:\” blablabla \“}和b_SET相同-可能有未知数量的集合-如c_SET d_SET等。 我尝试遍历行并在那里进行匹配:
for line in fileopened:
    setmatch = re.match( r\'^(createNode set -n \")(.*)(_SET)(.*)\' , line)
     if setmatch:
            sets.append(setmatch.group(2))
在这里找到匹配项后,我将遍历下几行以获取该集合的属性(test1,test2),直到找到新集合(例如c_SET或EOF)为止。 用re.MULTILINE一次性获取所有信息的最佳方法是什么?     
已邀请:
我懂了:
import re

filename = \'tr.txt\'

with open(filename,\'r\') as f:
    ch = f.read()

pat = re.compile(\'createNode newnode -n (\"\\w+?_SET\");(.*?)(?=createNode|\\Z)\',re.DOTALL)
pit = re.compile(\'^ *setAttr.+?(\"[^\"\\n]+\").+(\"[^\"\\n]+\");(?:\\n|\\Z)\',re.MULTILINE)

dic = dict( (mat.group(1),dict(pit.findall(mat.group(2)))) for mat in pat.finditer(ch)) 
print dic
结果
{\'\"b_SET\"\': {\'\".test2\"\': \'\"ehmehm\"\', \'\".test1\"\': \'\"hmm\"\'}, \'\"a_SET\"\': {\'\".test2\"\': \'\"blablabla\"\', \'\".test1\"\': \'\"blabla\"\'}}
。 题: 如果字符串中必须有字符“ 4”怎么办?如何表示? 。 编辑 我没有找到解决方案,因此我很难找到解决方案。 这是一个新模式,它捕获在字符串
\"    setAttr\"
之后且在下一个
\"    setAttr\"
之前的FIRST字符串
\"...\"
和LAST字符串
\"...\"
。因此,可以出现几个,5ѭ,不仅是3。您没有询问这种情况,但我认为可能是有必要的。 我还设法使字符串中出现换行符以捕捉
\"....\\n......\"
,而不仅是在它们周围。为此,我不得不为我发明一些新东西:
(?:\\n(?! *setAttr)|[^\"\\n])
意味着:接受所有字符,除了
\'\"\'
和常见的all13ѭ之外,还只接受不以
\' *setAttr\'
开头的行的换行符 对于
(?:\\n(?! *setAttr)|.)
,它表示:换行符后没有以
\' *setAttr\'
开头的行以及所有其他非换行符。 因此,匹配中会自动附加任何其他作为制表符的特殊序列或制表符。
ch = \'\'\'//Last modified: Sat, Apr 16, 2011 09:55:04 AM
//Codeset: ISO-8859-1
fileInfo \"version\" \"20x64\";
createNode newnode -n \"a_SET\";
    addAttr -ci true -k true -sn \"connections\" -ln \"connections\" -dt \"string\";
    setAttr -l on -k off \".tx\";
    setAttr -l on -k off \".ty\";
    setAttr -l on -k off \".sz\";
    setAttr -l on -k on \".test1\" -type \"string\" \"blabla\";
    setAttr -l on -k on \".test2\" -type \"string\" \"blablabla\";
createNode newnode -n \"b_SET\";
    addAttr -ci true -k true -sn \"connections\" -ln \"connections\" -dt \"string\";
    setAttr -l on -k off \".tx\";
    setAttr -l on -k off \".ty\";
    setAttr -l on -k off \".sz\";
    setAttr -l on -k on \".test1\" -type \"string\" (
      \"hmm bl
      abla\\tbla\" );
    setAttr -l on -k on \".tes\\nt\\t2\" -type \"string\" \"ehm\\tehm\";
    setAttr -l on -k on \".test3\" -type \"string\" \"too
    much\" \"pff\" \"\"\" \"feretini\" \"gol\\nolo\";
    \'\'\'

import re

pat = re.compile(\'createNode newnode -n (\"\\w+?_SET\");(.*?)(?=createNode|\\Z)\',re.DOTALL)
pot = re.compile(\'^ *setAttr.+?\'
                 \'\"((?:\\n(?! *setAttr)|[^\"\\n])+)\"\'
                 \'(?:\\n(?! *setAttr)|.)+\'
                 \'\"((?:\\n(?! *setAttr)|[^\"\\n])+)\"\'
                 \'.*;(?:\\n|\\Z)\',re.MULTILINE)

dic = dict( (mat.group(1),dict(pot.findall(mat.group(2)))) for mat in pat.finditer(ch)) 
for x in dic:
    print x,\'\\n\',dic[x],\'\\n\'
结果
\"b_SET\" 
{\'.test3\': \'gol\\nolo\', \'.test1\': \'hmm bl\\n      abla\\tbla\', \'.tes\\nt\\t2\': \'ehm\\tehm\'} 

\"a_SET\" 
{\'.test1\': \'blabla\', \'.test2\': \'blablabla\'}
    
您可以使用regexp正向前瞻来拆分组:
(yourGroupSeparator)(.*?)(?=yourGroupSeparator|\\Z)
在您的示例中:
import re

lines = open(\"e:/temp/test.txt\").read()
matches = re.findall(r\'createNode newnode \\-n (\\\"._SET\\\");(.*?)(?=createNode|\\Z)\', lines, re.MULTILINE + re.DOTALL);

for m in matches:
    print \"%s:\" % m[0], m[1]


\"\"\"
Result:
>>>
\"a_SET\":
    addAttr -ci true -k true -sn \"connections\" -ln \"connections\" -dt \"string\";
    setAttr -l on -k off \".tx\";
    setAttr -l on -k off \".ty\";
    setAttr -l on -k off \".sz\";
    setAttr -l on -k on \".test1\" -type \"string\" \"blabla\";
    setAttr -l on -k on \".test2\" -type \"string\" \"blablabla\";

\"b_SET\":
    addAttr -ci true -k true -sn \"connections\" -ln \"connections\" -dt \"string\";
    setAttr -l on -k off \".tx\";
    setAttr -l on -k off \".ty\";
    setAttr -l on -k off \".sz\";
    setAttr -l on -k on \".test1\" -type \"string\" \"hmm\";
    setAttr -l on -k on \".test2\" -type \"string\" \"ehmehm\";
\"\"\"
如果您希望将结果作为字典,则可以使用:
result = {}
for k, v in matches:
    result[k] = v   # or maybe v.split() or v.split(\";\")
在findall之后     
另一个可能的选择:
createNode newnode -n \"b_SET\";
    addAttr -ci true -k true -sn \"connections\" -ln \"connections\" -dt \"string\";
    setAttr -l on -k off \".tx\";
    setAttr -l on -k off \".ty\";
    setAttr -l on -k off \".sz\";
    setAttr -l on -k on \".test1\" -type \"string\" (
      \"hmm blablabla\" );
    setAttr -l on -k on \".test2\" -type \"string\" \"ehmehm\";
如您所见,\“。test1 \”值现在使用/ n行分隔符进行拆分。您如何使用eyquem的方法解决该问题?
pit = re.compile(\'^ *setAttr.+?(\"[^\"\\n]+\").+(\"[^\"\\n]+\");(?:\\n|\\Z)\',re.MULTILINE)
    

要回复问题请先登录注册