Javascript 如何在文本中实现对自己的html标记的解析

Javascript 如何在文本中实现对自己的html标记的解析,javascript,jquery,state-machine,Javascript,Jquery,State Machine,我的任务是实现自己的标签,使文本加粗,下划线或删除线与任何嵌套。 像一个 此外,我需要使自己的超链接像一个 [link | http://stackoverflow.com] 第一个想法出现了——它应用regexp。守则: View.prototype.parseText = function(text) { text = text.replace(/\*([^\*]+)\*/g, '<b>$1</b>'); text = text.replace(/\_([^\_]

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

此外,我需要使自己的超链接像一个

[link | http://stackoverflow.com]
第一个想法出现了——它应用regexp。守则:

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;};
View.prototype.parseText=函数(文本){
text=text.replace(/\*([^\*]+)\*/g,$1');
text=text.replace(/\ \([^\ \ \ \)\ \/g,$1');
text=text.replace(/\-([^\-]+)\-/g,$1');
text=text.replace(/\[([^\\\].+)\\\\[(.+)\]/g',);
返回文本;};

它正在工作,但我需要扩展性。正则表达式不是一个好主意,因为它是硬编码的。如何使用有限状态机(或任何jQuery插件)实现该任务?如果您有任何帮助,我将不胜感激。

也许您想使用现有的库,例如

如果您喜欢自己编写,那么我建议您查看源代码,看看它是如何解析的(可能还有其他语言中标记处理器的源代码)。给你的一些建议:

  • 使用jQuery操作标记
  • 不要使用正则表达式来解析语言。标记元素时会遇到问题 混合在一起

无论您做什么,要扩展标签系统,您都需要: 1.定义标记,然后 2.将其替换为等效的HTML

即使您用js编写自己的解析器,在一天结束时,您仍然需要执行上述两个步骤,因此它的可扩展性并不比您现在拥有的更高

除非您有其他需求(例如,as replace仅在这样一个元素中,但在另一个元素中执行其他操作,这需要解析),否则Regex是该作业的工具

您可以将regex调用包装在一个函数中,并在需要扩展该功能时向该函数添加regex替换。如果需要多个页面,请将其添加到外部js文件中

function formatUserContent(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;
}
函数formatUserContent(文本)
{
text=text.replace(/\*([^\*]+)\*/g,$1');
text=text.replace(/\ \([^\ \ \ \)\ \/g,$1');
text=text.replace(/\-([^\-]+)\-/g,$1');
text=text.replace(/\[([^\\\].+)\\\\[(.+)\]/g',);
返回文本;
}
完成后,扩展该功能就如同添加

text = text.replace(/\+([^\-]+)\+/g, '<em>$1</em>');
text=text.replace(/\+([^\-]+)\+/g,$1');
在函数体中。我怀疑推出自己的有限状态机会更容易扩展,恰恰相反

花几个小时在有限状态机上,希望它能在未来某个未知时间节省几分钟,这不是一项好的投资。。。当然,除非你想找个借口写一个有限状态机,在这种情况下,继续吧

作为补充说明,我建议让你的正则表达式更简单一点

text = text.replace(/\[([^\|].+)\|\s*(http://.+)\]/g, '<a href="$2">$1</a>');
text=text.replace(/\[([^\\\].+)\\\\\s*(http:/.+\]/g');

(除非您有可以为用户完成任务的UI元素)

我可以建议您使用以下实现

它使用状态设计模式(由于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();
/*视图定义*/
功能视图(容器){
this.container=容器;
这个;
该状态为0;
};
View.prototype.parse=函数(文本){
var self=这个;
这是.\u parsers.forEach(函数(e){
自我剖析(e);
});
返回this.container.innerHTML;
};
View.prototype.\u parse=函数(解析器){
var text=parser.parse(this.container.innerHTML);
this.container.innerHTML=文本;
返回文本;
};
View.prototype.nextState=函数(){
if(this.\u currentState
​让我更深入地了解一下实现。 首先,我们有一个基本的“类”(构造函数)视图。每个视图都有它的基本
容器和一个解析器列表,它还记得接下来应该应用哪个解析器

之后,我们有了名为
Parser
的“抽象类”(原型中的构造函数和抛出异常的方法),它定义了每个解析器必须实现的方法
parse

之后,我们只需定义不同的具体解析器并将它们添加到视图中。我们可以一个接一个地传递状态(
View
's
nextState
),或者在一个方法调用中传递所有状态(
View
's
parse
)。我们可以动态添加新的解析器

一件可以批准的事情是包括flyweight工厂来管理解析器

用“抽象的”缺点来解决问题
/* 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();