而[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