2016-12-12 2 views
1

私はMMORPGでDMingに使用されるプログラムを開発しようとしていましたが、必要な実際の正規表現の解析に問題があります。私はそれを取ったので、私は正式年からDiceRollerアドオンの上に撮影したと数年前、私はそれをたくさん作り直しました正規表現でXdY + ZまたはXdYを認識する

:以下、アクティブフォーラムで別のスレッドから自分自身を引用する

ゲームで多くのテストを行いました。私はまだ何もアップロードしていませんが、私はアドオンの設計にとって現在重要な正規表現を苦労しています。

いくつかの背景:DiceRollerアドオンの最新の反復により、raidチャットに "!XdY"(Xはダイスの数、Yはダイスの値)とタイプすることができます。アドオンのいくつかのロジック(乱数プロトコル)を経て、サイコロを加算した後に入力を吐き出します。

次のようにそれがある:

local count, size = string.match(message, "^!(%d+)[dD](%d+)$") 

は今、私はそれを行うために必要な機能は、「!XdY」OR「XdY + Z」の両方のために解析しているが、私は近づくことができないかのように思えます私はそれが両方の式を行うために必要なので、私はどの正規表現を使用するかに関係なく、 "XdY + Z"に変換します。必要に応じて、より多くのソースコードを提供することができます。

これは私が今まで得ている最も近い:

http://i.imgur.com/eMhPHQB.png

、これは正規表現式である:あなたが見ることができるように

local count, size, modifier = string.match(message, "^!(%d+)[dD](%d+)+?(%d+)$") 

、修飾子とそれだけで動作します良い。しかし、正規表現がそれが "XdY + Z"であると考えている修飾子を削除し、 "1d20"とすれば "1d2 + 0"だと思います。 1d200は "1d20 + 0"と思うでしょう。私はオプションの文字 "?"表現が全く機能しなくなるだけです。もし私がしたら!1d2それは動作しません。それはほとんどの場合、オプションの文字がそこにいる必要がありますか?

私はいつも正規表現に苦労しました。

答えて

1
local function dice(input) 
    local count, size, modifier = input:match"^!(%d+)[dD](%d+)%+?(%d*)$" 
    if count then 
     return tonumber(count), tonumber(size), tonumber("0"..modifier) 
    end 
end 

for _, input in ipairs{"!1d6", "!1d24", "!1d200", "!1d2+4", "!1d20+24"} do 
    print(input, dice(input)) 
end 

出力:

!1d6  1 6 0 
!1d24 1 24 0 
!1d200 1 200 0 
!1d2+4 1 2 4 
!1d20+24 1 20 24 
+1

これは '!1d2 +'も通過させますが、この場合は問題ではありません。 –

+0

@PaulKulchenko - '" ^!(%d +)[dD](%d +)%+?(%d *)%f [%D] $ "'は '+'で終了した文字列を拒否します。 –

+0

これは機能しました。 3番目のキャプチャグループから値が与えられなかった場合、プログラムがクラッシュするという2番目の問題が発生しました。しかし、それは代わりに ""終わるので、私はちょうどそれが来たようにそれを修正しました! ありがとうございました! – Hranu

0

正規表現は非常に限定されています。 ^!(%d+)[dD](%d+)(?:+(%d+))?$を使用する必要がありますが、これはサポートされていません。これは、非キャプチャグループとグループの修飾子を使用する(?:+(%d+))?があり、どちらもLuaパターンでサポートされていないためです。

this oneのような正規表現ライブラリを使用すると、最も完全なエンジンの1つであるPCRE、PHP regex engineを使用することを検討してください。しかし、あなたはこの正規表現のためにそれを使用したい場合は、それは残忍だろう。あなたはコードでそれをやることができますが、このような簡単な作業ではそれほど難しくありません。

0

Luaのパターンは一つの式(彼らは、オプションのグループをサポートしていないとして)、二つの式でそれを処理するための簡単なオプションがあると、これを解析するのに十分強力ではありませんが:

-- check the longer expression first 
local count, size, modifier = string.match(message, "^!(%d+)[dD](%d+)+(%d+)$") 
if not count then 
    count, size = string.match(message, "^!(%d+)[dD](%d+)$") 
end 
+0

'+'は '%'でエスケープする必要がありますか? –

+0

実際、パーセントなしで動作します( '+'についてのエラーを発生させるのではなく、グループに適用できません) –

+0

右; '(何か)+'は有効なパターンです。 –