javascript - 如何实现对文本中自己的html标签的解析

标签 javascript jquery state-machine

我的任务是实现自己的标签,使文本粗体、下划线或带有任何嵌套的删除线。 像一个

*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 中。我们可以一个一个地传递状态(ViewnextState)或者在一个方法调用中传递所有状态(View >解析)。我们可以动态添加新的解析器。

可以批准的事情包括用于管理解析器的享元工厂。

使用“抽象”构造函数的方法在实现不同的模式(例如模板方法)时也非常有用。

  • 由于所有这些构造函数和对象的定义,编辑可能会有一点开销。一切都可以通过回调来完成,即每个状态都是一个不同的函数。我之所以使用这种方法,是因为我一直在寻找最容易理解的、从特定于语言的功能中清楚的答案。我希望我做到了。

关于javascript - 如何实现对文本中自己的html标签的解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14003903/

相关文章:

javascript - 理解嵌套三元运算符的简单方法?

javascript - Sequelize - Node Js - 枚举和整数字段搜索选项

javascript - 添加幻灯片后初始化 slider

javascript - 如何使用 Prototype 或 JQuery 获取所选单选按钮的值

ruby-on-rails - rails : Multi-Step New User Signup Form (FSM? )

javascript - 如何将自定义颜色添加到 extjs 条形图

javascript - 允许用户将多个不同的对象重新排序在一起

javascript - jQuery 动画意外滞后

finite-automata - NFA 相对于 DFA 的优点/缺点,反之亦然

uml - BoUML 的状态机生成器是否正确处理复合状态的退出和进入?