我的任务是实现自己的标签,使文本粗体、下划线或带有任何嵌套的删除线。 像一个
*bold text* _underlinetext_ -strikethrough-
我还需要像这样制作自己的超链接
[link | http://stackoverflow.com]
出现的第一个想法 - 它应用正则表达式。代码:
View.prototype.parseText = function(text) {
text = text.replace(/\*([^\*]+)\*/g, '<b>$1</b>');
text = text.replace(/\_([^\_]+)\_/g, '<u>$1</u>');
text = text.replace(/\-([^\-]+)\-/g, '<s>$1</s>');
text = text.replace(/\[([^\|].+)\|(.+)\]/g, '<a href="$2">$1</a>');
return text;};
它可以工作,但我需要可扩展性。正则表达式不是一个好主意,因为它是硬编码的。如何使用有限状态机(或任何 jQuery 插件)实现该任务?如果有任何帮助,我将不胜感激。
最佳答案
我可以建议您执行以下操作 http://jsfiddle.net/NwRCm/5/
它使用 State 设计模式(由于 JavaScript 和目的而略有修改)。在表面之下,所有状态都是使用正则表达式实现的,但在我看来,这是最有效的方式。
/* View definition */
function View(container) {
this.container = container;
this._parsers = [];
this._currentState = 0;
};
View.prototype.parse = function(text) {
var self = this;
this._parsers.forEach(function (e) {
self._parse(e);
});
return this.container.innerHTML;
};
View.prototype._parse = function (parser) {
var text = parser.parse(this.container.innerHTML);
this.container.innerHTML = text;
return text;
};
View.prototype.nextState = function () {
if (this._currentState < this._parsers.length) {
return this._parse(this._parsers[this._currentState++]);
}
return null;
};
View.prototype.addParser = function (parser) {
if (parser instanceof Parser) {
return this._parsers.push(parser);
} else {
throw 'The parser you\'re trying to add is not an instance of Parser';
}
};
/* end of the View definition */
/* Simulation of interface */
function Parser() {};
Parser.prototype.parse = function () {
throw 'Not implemented!';
};
/* Implementation of bold parser */
function BoldParser() {};
BoldParser.prototype = new Parser();
BoldParser.prototype.parse = function (text) {
text = text.replace(/\*([^\*]+)\*/g, '<b>$1</b>');
return text;
};
/* Implementation of underline parser */
function UnderlineParser() {};
UnderlineParser.prototype = new Parser();
UnderlineParser.prototype.parse = function (text) {
text = text.replace(/\_([^\_]+)\_/g, '<u>$1</u>');
return text;
};
/* Link parser */
function LinkParser() {};
LinkParser.prototype = new Parser();
LinkParser.prototype.parse = function (text) {
text = text.replace(/\[([^\|].+)\|(.+)\]/g, '<a href="$2">$1</a>');
return text;
};
var v = new View(document.getElementById('container'));
v.addParser(new UnderlineParser());
v.addParser(new BoldParser());
v.addParser(new LinkParser());
v.nextState();
v.nextState();
v.nextState();
让我看一下更深入的实现。
首先我们有一个基“类”(构造函数) View 。每个 View 都有它的基础 容器
和一个解析器列表,它还会记住接下来应该应用哪个解析器。
之后我们有了名为 Parser
的“抽象类”(原型(prototype)中带有方法的构造函数),它定义了一个必须实现的方法 parse
由每个解析器。
之后,我们只需定义不同的具体解析器并将它们添加到 View 中。我们可以一个一个地传递状态(View
的 nextState
)或者在一个方法调用中传递所有状态(View
的 >解析
)。我们可以动态添加新的解析器。
可以批准的事情包括用于管理解析器的享元工厂。
使用“抽象”构造函数的方法在实现不同的模式(例如模板方法)时也非常有用。
- 由于所有这些构造函数和对象的定义,编辑可能会有一点开销。一切都可以通过回调来完成,即每个状态都是一个不同的函数。我之所以使用这种方法,是因为我一直在寻找最容易理解的、从特定于语言的功能中清楚的答案。我希望我做到了。
关于javascript - 如何实现对文本中自己的html标签的解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14003903/