pyparsing を使用して、ネストされている可能性のある化学式を解析し、pyparsing を使用して非整数の化学量論を解析しようとしています。私が欲しいのは、式に存在する各要素のリストと、それに対応する総化学量論です。
私は pyparsing wiki の例を最初に使用し、さらに多くのアイデアを得るために fourFn.py を調べました。パッケージ内のすべての機能を使用する方法がわかりません。
私は次の文法を思いつきました:
from pyparsing import Word, Group, ZeroOrMore, Combine,\
Optional, OneOrMore, ParseException, Literal, nums,\
Suppress, Dict, Forward
caps = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
lowers = caps.lower()
digits = "0123456789"
integer = Word( digits )
parl = Literal("(").suppress()
parr = Literal(")").suppress()
element = Word( caps, lowers )
separator = Literal( "," ).setParseAction(lambda s,l,t: t[0].replace(',','.')) | Literal( "." )
nreal = (Combine( integer + Optional( separator +\
Optional( integer ) ))\
| Combine( separator + integer )).setParseAction( lambda s,l,t: [ float(t[0]) ] )
block = Forward()
groupElem = Group( element + Optional( nreal, default=1)) ^ \
Group( parl + block + parr + Optional( nreal,default=1 ) )
block << groupElem + ZeroOrMore( groupElem )
formula = OneOrMore( block )
ネストされていない数式は期待どおりに機能します。
>>> formula.parseString('H2O')
([(['H', 2.0], {}), (['O', 1], {})], {})
これらの空のフィールド (用途が見つかりませんでした) があるにもかかわらず、必要な情報を抽出できます。
しかし、次のようなことを試みると:
>>> formula.parseString('C6H8(OH)4')
([(['C', 6.0], {}), (['H', 8.0], {}), ([(['O', 1], {}), (['H', 1], {}), 4.0], {})], {})
数式が正しく解析されていることがわかりますが、(OH)4 の外側の '4' で内側の数値を乗算したいと考えています。しかし、私はそれを行う方法がわかりません。
あるトークンが別のトークンの値を変更するにはどうすればよいですか?
または、これらの結果を調べて、ブロックに外側の数値が付加されている場合に、ブロック内の各要素の合計数を計算できる関数を作成するにはどうすればよいでしょうか?
前もって感謝します。
edit1:次のようなものが必要だと思います:「(ブロック)nreal」の発生時に外側のnrealを抑制し、nrealのすべての発生を外側の値で乗算します...