而[B]嵌套[I]可以[/ B],而[/ i]於醜
我已經寫了非常相似,你正在尋找不同的是它做什麼解析器會在你的第四個例子上拋出一個錯誤。 「[i]中的」意外結束標記[/ b]「)。
我認爲你需要做的是非常可行的,但在內部,你會想創建一個樹,如果你的原文是:
"And the [b]nesting [i]can be[/i][/b][i] rather[/i] ugly"
。 (如果以後不需要將其轉換爲XML,我認爲這不是必需的,如果不需要轉換爲XML,則可以保留一個鏈接的文本部分列表,其中每個部分都標有其格式組合)
兩種可能的方法對這一問題浮現在腦海中(當然可能有更大的可能性)。 1)預處理並插入缺失的末端,並在必要時開始標記。 2)構建你的分析樹,並在有重疊標記的地方暗示基於當前上下文的缺失樹。我認爲方法編號(2)會更簡單和更清晰。
你可以根據你在哪裏有一個AbstractElement類,擴展AbstractElement對於TextElement類,以及延伸AbstractElement,幷包含類型AbstractElement的子元素列表的標籤類的複合模式,將樹模型。
您將通過創建一個根標籤的實例啓動。然後你會調用rootTag.parse(文本)。您需要一個可以返回3種令牌的掃描器:文本,開始標籤和結束標籤。掃描儀將允許您將令牌推送到它上面,它會在任何正常掃描的令牌之前返回。這將允許您在遇到並處理意外的結束標記後推送新的開始標記標記。您還需要知道何時完成輸入。我將爲此使用第4種標記類型。
/* methods within class Tag */
public void parse(String text) {
MyScanner scanner = new MyScanner(text);
parse(scanner);
}
/* returns next token */
private Token parse(MyScanner scanner) {
Token firstToken = scanner.getNextToken();
return parse(scanner,firstToken);
}
private Token parse(MyScanner scanner) {
Token firstToken = scanner.getNextToken();
return parse(scanner,firstToken);
}
private Token parse(MyScanner scanner, Token token) {
while (!token.isDone() && !token.isEndTag()) {
if (token.isStartTag()) {
Tag subTag = new Tag(token.getValue());
token = scanner.getNextToken();
token = subTag.parse(scanner,token);
addElement(subTag);
}
else {
TextElement text = new TextElement(token.getValue());
addElement(text);
token = scanner.getNextToken();
}
}
if (token.isEndTag()) {
if (!token.getValue().equals(getName()) {
scanner.push(new Token(Token.START_TAG,token.getValue()));
}
else {
token = scanner.getNextToken();
}
}
return token;
}
所以,如果你是解析 「和[b]嵌套[I]可以[/ B],而[/ i]於醜」,下面應該得到建立。
rootTag.parse should be adding:
TextElement: "And the "
Tag: "b"
TextElement: "nesting "
Tag: "i"
TextElement: "can be"
(... at this point the odd [/b] is encountered ...)
(... push "i" start tag on the scanner ...)
(... here the [/b] is encountered (again) ...)
Tag: "i" (this was scanned because it had been pushed to the scanner)
TextElement: " rather"
TextElement: " ugly"
注意:文本區域內的編碼不適合測試和調試。接受這個答案作爲提示或可能性,而不是你的確定答案。
哇。非常感謝你。你的示例代碼幾乎解決了我所有的問題:) – 2010-01-20 11:20:44
謝謝,祝你好運。我只是修正了一個錯字,並且在推送調用中傳遞了錯誤的參數,現在也修復了這個錯誤。 – rayd09 2010-01-20 17:06:44