如何使用 txr 查询捕获此计算机输出?

How can I capture this computer output with a txr query?

我有以下数据来自计算机程序输出的文本:

[Coordination geometry type : Single neighbor (IUCr: [1l])

   - coordination number : 1
 ------------------------------------------------------------,
 Coordination geometry type : Linear (IUPAC: L-2 || IUCr: [2l])

   - coordination number : 2
 ------------------------------------------------------------,
 Coordination geometry type : Anticuboctahedron (IUCr: [12aco])

   - coordination number : 12
 ------------------------------------------------------------,
 Coordination geometry type : Square cupola

   - coordination number : 12
 ------------------------------------------------------------,
 Coordination geometry type : Hexagonal prism (IUPAC: HPR-12 || IUCr: [12p])

   - coordination number : 12
 ------------------------------------------------------------,
 Coordination geometry type : Hexagonal antiprism (IUPAC: HAPR-12)

   - coordination number : 12
 ------------------------------------------------------------,
 Coordination geometry type : Square-face capped hexagonal prism

   - coordination number : 13
 ------------------------------------,------------------------,
 Coordination geometry type : Unknown environment

   - coordination number : None
 ------------------------------------------------------------,
 Coordination geometry type : Unclear environment

   - coordination number : None
 ------------------------------------------------------------]

我想编写一个 txr 查询来捕获此数据并生成以下 CSV table:

cnum,geom,IUPAC,IUCr
1,single neighbor,,[1l]
2,linear,L-2,
2,linear,,[2l]
12,anticuboctahedron,,[12aco]
12,square cupola,,
12,hexagonal prism,HPR-12,
12,hexagonal prism,,[12p]
12,hexagonal antiprism,HAPR-12,
13,square-face capped hexagonal prism,,
,unknown environment,,
,unclear environment,,

我认为查询应该是这样的:

@(collect :vars (cnum geom IUPAC IUCr))
@/ |\[/Coordination geometry type : @geom @(maybe)(IUPAC: @IUPAC@(maybe) || IUCr: @IUCr(@end))@(end)

   - coordination number : @cnum
 ------------------------------------------------------------,   
@(last)
 ------------------------------------------------------------] 
@(end)
@(output)
cnum,geom,IUPAC,IUCr
@(repeat)
@cnum,@(do (downcase-str @geom)),@IUPAC,@IUCr
@(end)
@(end)

但是我遇到了一些语法错误和困惑。具体来说:

由于此输出以括号列表的形式显示,我不清楚如何捕获第一行。我认为也许正则表达式可以解决问题,但这似乎效率不高。另外,我不清楚这是否是正确的语法。 [ 应该转义吗?我可以使用 @(repeat) 指令中提到的 @(first) 来处理这种情况吗?

IUPACIUCr 是存在于由 || 分隔的括号内的可选变量。我认为这些可能被 @(maybe) 捕获,但我不确定该指令的确切工作方式以及它是否可以嵌套。如果两者都未指定,则不会有括号(与方形冲天炉一样)。

为了向我自己和其他人提供更多示例来学习这个强大的工具,我想我可能会 post 在这里回答这个问题。

试试这个:

@(collect :vars (cnum geom (IUPAC "") (IUCr "")))
@  (cases)
@/[ \[]/Coordination geometry type : @geom (IUPAC: @IUPAC || IUCr: @IUCr)
@  (or)
@/[ \[]/Coordination geometry type : @geom (IUPAC: @IUPAC)
@  (or)
@/[ \[]/Coordination geometry type : @geom (IUCr: @IUCr)
@  (or)
@/[ \[]/Coordination geometry type : @geom
@  (end)

   - coordination number : @cnum
@(last)
 ------------------------------------------------------------]
@(end)
@(output)
cnum,geom,IUPAC,IUCr
@  (repeat)
@cnum,@{geom :filter :downcase},@IUPAC,@IUCr
@  (end)
@(end)

您的原始代码中的语法错误是由 (@end) 拼写错误引起的;修复它并且 txr 接受它。不幸的是,它不起作用。

第一个区别是在collect:vars中,我们给了可选变量默认值。如果没有这些,在它们不发生的情况下未能绑定它们将触发失败。

是的,maybe确实嵌套了,我们可以这样解决。然而,以一些重复为代价,面向行的 cases 以一种易于阅读的方式处理案例。

注意案例的顺序很重要。

我们不匹配 ...----, 分隔线。这样做只会阻止我们匹配以 ...---] 结尾的最后一条记录。请注意,last 子句为整个 collect 主体指定了替代模式,而不仅仅是最后一行的替代模式。我们保留它以提供终止测试。可能根本没有必要。如果数据后跟其他 material 可能会增加误报匹配或浪费大量时间,我们需要此测试。

output中不能使用do;没有这样的指令。 (do 实际上在那里被解释为 Lisp)。我使用输出过滤器来缩小几何图形。如果使用 @(downcase-str geom),那么我们需要在 repeat 中使用 :vars (geom),因为 geom 只会出现在 Lisp 表达式中,而 repeat 相当幼稚,不分析要自动迭代的变量的 Lisp 代码。


这里有一个减少案例重复的方法,使用模式函数来保持整洁:

@(define formula (x y))@\
  @(cases) (IUPAC: @x || IUCr: @y)@\
  @(or) (IUPAC: @x)@\
  @(or) (IUCr: @y)@\
  @(or)@(eol)@\
  @(end)@\
@(end)
@(collect :vars (cnum geom (IUPAC "") (IUCr "")))
@/[ \[]/Coordination geometry type : @geom@(formula IUPAC IUCr)

   - coordination number : @cnum
@(last)
 ------------------------------------------------------------]
@(end)
@(output)
cnum,geom,IUPAC,IUCr
@  (repeat)
@cnum,@{geom :filter :downcase},@IUPAC,@IUCr
@  (end)
@(end)