regex - 具有数组属性的 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并带有要测试的案例
解决方案
这是一个解决方案,从您在测试用例中使用正则表达式达到的点继续:
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
推荐阅读
- azure - 未找到类型或命名空间“BlobAttribute”
- android - 为什么可以从 Android 8.0 中的工作线程访问视图?
- haskell - Megaparsec ParsecT 的状态不回溯
- python - 如何使用正则表达式删除字符串中出现在单词两侧的各种标签?
- android - Android JDBC连接导致ctahttp异常
- r - 统计问题。如何从 R 中 N(1,3) mean = 1 and sd = 3 的总体/矩阵中提取样本大小 x
- mysql - 从字符串中提取特定文本
- sockets - 无需使用 http.Serve 即可激活 Go TLS Socket 服务器服务
- wordpress - 在子站点的根路径 Wordpress Multisite 上上传文件
- ruby - 两者都实时获取 STDOUT 并提供 STDIN