首页 > 解决方案 > 具有数组属性的 IFC 正则表达式

问题描述

IFC 是用于建筑项目的 STEP 文件的变体。IFC 包含有关正在建造的建筑物的信息。该文件是基于文本的,易于阅读。我正在尝试将这些信息解析为 python 字典。每行的一般格式将类似于以下

2334=IFCMATERIALLAYERSETUSAGE(#2333,.AXIS2.,.POSITIVE.,-180.);

理想情况下,这应该被解析为 int #2334, IFCMATERIALLAYERSETUSAGE, #2333,.AXIS2.,.POSITIVE.,-180。我发现一个解决方案正则表达式在第一个匹配 https://regex101.com/r/RHIu0r/10中包含两个匹配项,以解决部分问题。但是,在某些情况下,数据包含数组而不是值,如下例所示

2335=IFCRELASSOCIATESMATERIAL('2ON6$yXXD1GAAH8whbdZmc',#5,$,$,(#40,#221,#268,#281),#2334);

这种情况需要解析为#2335, IFCRELASSOCIATESMATERIAL, '2ON6$yXXD1GAAH8whbdZmc', #5,$,$, [#40,#221,#268,#281],#2334 其中[#40,#221,# 268,#281] 是一个以数组形式存储在单个变量中的数组,该数组可以是中间变量,也可以是最后一个变量。

您能否协助创建正则表达式以获得所需的结果我创建了https://regex101.com/r/mqrGka/1并带有要测试的案例

标签: regexifc

解决方案


这是一个解决方案,从您在测试用例中使用正则表达式达到的点继续:

file = """\
#1=IFCOWNERHISTORY(#89024,#44585,$,.NOCHANGE.,$,$,$,1190720890);
#2=IFCSPACE(';;);',#1,$);some text);
#2=IFCSPACE(';;);',#1,$);
#2885=IFCRELAGGREGATES('1gtpBVmrDD_xsEb7NuFKc8',#5,$,$,#2813,(#2840,#2846,#2852,#2858,#2879));
#2334=IFCMATERIALLAYERSETUSAGE(#2333,.AXIS2.,.POSITIVE.,-180.);
#2335=IFCRELASSOCIATESMATERIAL('2ON6$yXXD1GAAH8whbdZmc',#5,$,$,(#40,#221,#268,#281),#2334);
""".splitlines()

import re
d = dict()
for line in file:
    m = re.match(r"^#(\d+)\s*=\s*([a-zA-Z0-9]+)\s*\(((?:'[^']*'|[^;'])+)\);", line, re.I|re.M)
    attr = m.group(3)       # attribute list string
    values = [m.group(2)]   # first value is the entity type name
    while attr:
        start = 1
        if attr[0] == "'": start += attr.find("'", 1)   # don't split at comma within string
        if attr[0] == "(": start += attr.find(")", 1)   # don't split item within parentheses
        end = attr.find(",", start)                     # search for a comma / end of item
        if end < 0: end = len(attr)
        value = attr[1:end-1].split(",") if attr[0] == "(" else attr[:end]
        if value[0] == "'": value = value[1:-1]         # remove quotes
        values.append(value)
        attr = attr[end+1:]                             # remove current attribute item
    d[m.group(1)] = values                              # store into dictionary

推荐阅读