インストールレスプログラミング( ´ー`)

VBA , JavaScript , HTAなど 365アプリはインストール必要ですが、仕事に無いケースはほぼないから(・_・;)

正規表現 復習中 化学反応式を分解する

ずいぶん以前にも同じことをやってて,化学反応式の係数を調整するやつを作っていました。

マクロ以外の部分に依存すると,けっこうこまごまと調整が面倒で,どうせならマクロだけで全部作れないかと,少しやり始めたところ。

各元素の原子の数は正規表現を利用したほうがいいし,問題を簡単に作れる方がいいなと思います。

今は追われてはいないので,のんびりやっていこう。。

さて,化学反応式の分解部分だけのコードがある程度形になったので載せてみる。Microsoft VBScriptRegular Expression5.5への参照設定をしている前提です。

Sub 正規表現()

    Dim RegObj As RegExp: Set RegObj = New RegExp
    Dim MatchObj As MatchCollection, 化学反応式 As String
    化学反応式 = "C3H8+5O2→3CO2+4H2O"
    
    With RegObj
        .Global = True  '複数マッチ 大事!
        .Pattern = "([+→])|([^+→])+"
        Set MatchObj = .Execute(化学反応式)
    End With
    
    Dim 化合物()
    ReDim 化合物(1 To (MatchObj.Count + 1) / 2)
    
    Dim 反応物数 As Long, i As Long, j As Long
    Dim 化合物分解() As MatchCollection
    ReDim 化合物分解(1 To (MatchObj.Count + 1) / 2)
    j = 1
    For i = 1 To MatchObj.Count
        If MatchObj(i - 1).Value <> "+" Then
            If MatchObj(i - 1) = "→" Then
                反応物数 = i / 2
            Else
                化合物(j) = MatchObj(i - 1)
                j = j + 1
            End If
        End If
    Next


    For i = 1 To UBound(化合物)
        With RegObj
            .Pattern = "([0-9]+|[A-Z][a-z]?)"
            Set 化合物分解(i) = .Execute(化合物(i))
        End With
    Next
    Stop

End Sub

Dictionaryオブジェクトも絡めながら各元素の数をうまいこと処理したいなぁという気持ちを持ちつつまだ途中。

これを実行すると,
f:id:chemiphys:20180928192049p:plain

1.まず係数を含めた形で化合物()って配列に放り込む。
2.反応物が化合物の何番までかってのを生成物数に書き込んでおく。
3.各化合物をさらに各元素や係数に分解していく。

久々に正規表現なんか使うとほんと全くさっぱりで,しかもGlobalをTrueにしてなかったせいで,一つしか値がとれずに延々数時間考えた。

私は記憶力が無いので仕方ないんですが,それで調べ回る先が自分のブログという堂々巡り。

本当は,Submatchesというコレクションがせっかくあるんだからそれもうまく使ってスマートにやりたいんですが,今は全くだめだめです。

化学反応式   →  反応物と生成物に分ける  → 各元素の数を調べる → 係数を変えれるように準備

と,やりたい先はあるんですが,自分の現状を吐き出すと,気づくことも多いのでとりあえず書き残した。

正規表現って複雑なことをとても短いコードでやってくれる。

使いこなしたいけど,さっぱりですね。トライアンドエラーでしかやれないや(;´▽`A``