另一種解決方案使用正則表達式。
這個想法是遞歸地解析匹配葉子節點和表達式的輸入字符串。 parse
方法的每個調用都將匹配它的整個輸入,並返回一個帶有輸入值的節點(如果它是一個葉)或帶有兩個遞歸評估的子節點的節點(如果它匹配「表達式運算符表達式「)。
在其目前的形式,它需要高度規則輸入:
- 葉必須在形式位:upperCaseCharacter沒有括號操作者和表達式之間
- 一個空間
- 一個表達式可以是一個葉或東西括在內
每當正則表達式匹配,所有匹配的組被收集和空值被刪除。將會有8個非空組(因爲分組括號的數量總是相同的),並且內部組將總是數字2,3和5,其中3是運算符,2和5是左邊的輸入並且右節點。
toString
該方法簡單地寫出在波蘭表示法(運EX1 EX2)的表達。
class Node {
String value
Node left, right
static leaf = /(\d:[A-Z])/
static op = /([&|])/
static par = /\((.+)\)/
static parse(String text) {
if (text ==~ "^$leaf\$") {
return new Node(value: text)
}
def matcher = text =~ "^($leaf|$par) $op ($leaf|$par)\$"
if (matcher.matches()) {
def (l,o,r) = (matcher[0] - null)[2,3,5]
return new Node(left: parse(l), value: o, right: parse(r))
}
throw new IllegalArgumentException("Irregular input: $text")
}
String toString() {
left && right ? "$value $left $right" : value
}
}
例子:
println Node.parse('1:A')
println Node.parse('1:A & 2:B')
println Node.parse('(1:A & 2:B) | 3:C')
println Node.parse('(1:A & ((2:B | 3:C) & (4:D | 5:E))) | (6:F & 7:G)')
產生如下的波蘭式的輸出:
1:A
& 1:A 2:B
| & 1:A 2:B 3:C
| & 1:A & | 2:B 3:C | 4:D 5:E & 6:F 7:G
幾乎所有的東西我需要什麼。我試圖改變葉子模式沒有成功。在我的情況下,可能會比例子中的東西複雜一些。比方說,經過UUID和字:(字(詞)的情況下,我也許可以用\ w,但我停在UUID)。每當我試圖改變正則表達式得到一個異常。 – ajuszczak
你能提供一個例子嗎?如果是這樣,我可以放棄它。 – Steinar
682be428-25af-4a96-b057-0a9f28f40bcf:運動或54bc9a00-d030-4e63-9ded-a8c52063802d:旅遊(UUID v4和字) – ajuszczak