2016-12-12 13 views
1

我一直在試圖開發一個程序,將在MMORPG中使用DMing,但我在解析實際正則表達式時遇到了麻煩。正則表達式識別XdY + Z或XdY

從另一個線程引用自己在一個不太活躍的論壇:

我已經正式接管了DiceRoller插件從多年以前,我已經重新設計了很多,因爲我已經把它做爲並在遊戲中進行了大量測試。雖然我還沒有上傳任何東西,但我一直在努力尋找目前對插件設計至關重要的正則表達式。

一些背景:DiceRoller插件的最新迭代使得它可以在raid聊天中輸入「!XdY」(其中X是骰子的數量,Y是骰子值),並且擁有該插件的DM將會通過插件中的一些邏輯(隨機數lua協議),然後在添加骰子後吐出一個輸入。

其計算方法如下:

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

現在我需要做的是分析兩個「XDY!」或「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它不起作用。這幾乎就像可選角色NEEDS在那裏?

感謝您提前的幫助,我一直在努力與正則表達式。

回答

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

這工作;最終成爲第二個問題,如果修改器從未從第三個捕獲組獲得值,那麼它只會使程序崩潰。但它最終會變成「」,所以我只是把它固定下來! 謝謝! – Hranu

0

Lua正則表達式非常有限。您需要使用^!(%d+)[dD](%d+)(?:+(%d+))?$,但由於(?:+(%d+))?對組使用非捕獲組和修飾符,因此不會受支持,兩者都不受Lua模式支持。

考慮使用像this one這樣的正則表達式庫,它允許您使用PCRE,PHP正則表達式引擎,它是最完整的引擎之一。但是如果你只是想用這個正則表達式的話,那就太過分了。你可以通過代碼來做到這一點,對於像這樣的簡單任務來說不會那麼困難。

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

正確; '(某物)+'是一種有效的模式。 –