正規表現 復習中 化学反応式を分解する
ずいぶん以前にも同じことをやってて,化学反応式の係数を調整するやつを作っていました。
マクロ以外の部分に依存すると,けっこうこまごまと調整が面倒で,どうせならマクロだけで全部作れないかと,少しやり始めたところ。
各元素の原子の数は正規表現を利用したほうがいいし,問題を簡単に作れる方がいいなと思います。
今は追われてはいないので,のんびりやっていこう。。
さて,化学反応式の分解部分だけのコードがある程度形になったので載せてみる。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オブジェクトも絡めながら各元素の数をうまいこと処理したいなぁという気持ちを持ちつつまだ途中。
これを実行すると,
1.まず係数を含めた形で化合物()って配列に放り込む。
2.反応物が化合物の何番までかってのを生成物数に書き込んでおく。
3.各化合物をさらに各元素や係数に分解していく。
久々に正規表現なんか使うとほんと全くさっぱりで,しかもGlobalをTrueにしてなかったせいで,一つしか値がとれずに延々数時間考えた。
私は記憶力が無いので仕方ないんですが,それで調べ回る先が自分のブログという堂々巡り。
本当は,Submatchesというコレクションがせっかくあるんだからそれもうまく使ってスマートにやりたいんですが,今は全くだめだめです。
化学反応式 → 反応物と生成物に分ける → 各元素の数を調べる → 係数を変えれるように準備
と,やりたい先はあるんですが,自分の現状を吐き出すと,気づくことも多いのでとりあえず書き残した。
正規表現って複雑なことをとても短いコードでやってくれる。
使いこなしたいけど,さっぱりですね。トライアンドエラーでしかやれないや(;´▽`A``