0

我需要创建一个包含样式信息的字符串的 Javascript 对象表示。样式标识符并不重要,但为了这个问题,让我们使用 stackoverflow 使用的标识符:

    *text* = italic
    **text** = bold
    ***text*** = bold italic

我想创建的数据表示是一个对象数组,按照它们出现在字符串中的顺序,每个对象如下:

{
  stringpart : (string),
  style : (normal | bold | italic | bold italic)
}

因此给出以下字符串:

This is some example text, with some **bold** and *italic* ***styles***.

应转换为以下对象数组:

[
    {
      stringpart : "This is some example text, with some ",
      style : "normal"
    },
    {
      stringpart : "bold",
      style : "bold"
    },
    {
      stringpart : " and ",
      style : "regular"
    },
    {
      stringpart : "italic",
      style : "italic"
    },
    {
      stringpart : " ",
      style : "normal"
    },
    {
      stringpart : "styles",
      style : "bold italic"
    },
    {
      stringpart : ".",
      style : "normal"
    }
]

到目前为止,我已经开始研究 html 解析器并遇到以下代码:

var
    content = 'This is some <b>really important <i>text</i></b> with <i>some <b>very very <br>very important</b> things</i> in it.',
    tagPattern = /<\/?(i|b)\b[^>]*>/ig,
    stack = [],
    tags = [],
    offset = 0,
    match,
    tag;

while (match = tagPattern.exec(content)) {
    if (match[0].substr(1, 1) !== '/') {
        stack.push(match.index - offset);
    } else {
        tags.push({
            tag: match[1],
            from: stack.splice(-1, 1)[0],
            to: match.index - offset
        });
    }
    offset += match[0].length;
}
content = content.replace(tagPattern, '');
// now use tags array and perform needed actions.

// see stuff
console.log(tags);
console.log(content);
//example of correct result
console.log(content.substring(tags[3].from, tags[3].to)); 

虽然此代码中的正则表达式可用于检测上述样式标识符,但它不会以所需格式输出数据,因为它只是从索引返回/返回索引。

如何使用上述标识符有效地将字符串转换为所需的数组/对象表示?

4

2 回答 2

1

我想这会让你走得很远

var str = "This is some example text, with some **bold** and *italic* ***styles***."
str.match(/(\*{1,3})[^*]+(\1)/g);

正则表达式可视化

输出

[ '**bold**',
  '*italic*',
  '***styles***' ]

使用\1 反向引用的方便之处在于您将能够匹配*对。也就是说, single*会寻找下一个 single *,而 double**会寻找下一个 double ,等等。


我不打算这样做,但是呃,我有点无聊

var getStyleTokens = function(str) {

  var parts = [];

  var addNode = function(text, style) {
    return parts.push(
      {stringpart: text, style: style}
    );
  };

  var styles = {
    "*":   "italic",
    "**":  "bold",
    "***": "bold italic"
  };

  var re = /(\*{1,3})([^*]+)(?:\1)/g,
      caret = 0,
      match;

  while ((match = re.exec(str)) !== null) {
    console.log(match);
    addNode(str.substr(caret, match.index), "normal")
    addNode(match[2], styles[match[1]]);
    caret = match.index + match[0].length;
  };

  addNode(str.substr(caret), "normal");

  return parts;
};

var str = "This is some example text, with some **bold** and *italic* ***styles***."

getStyleTokens(str);

输出

[ { stringpart: 'This is some example text, with some ',
    style: 'normal' },
  { stringpart: 'bold', style: 'bold' },
  { stringpart: ' and ', style: 'normal' },
  { stringpart: 'italic', style: 'bold' },
  { stringpart: ' ', style: 'normal' },
  { stringpart: 'styles',
    style: 'bold italic' },
  { stringpart: '.', style: 'normal' } ]

笔记!

由于您的标签不太可能是 all *,因此最好在第一个捕获组中编写可能的标签列表。但是,这意味着 RegExp 的其余部分也发生了变化。

/(\*|\*\*|\*\*\*)(?:.(?!\1))+.(\1)/

正则表达式可视化

这意味着你可以写类似

/(BOLD|ITALIC|BOTH)(?:.(?!\1))+.(\1)/

正则表达式可视化

这将适用于这样的字符串

这是一些示例文本,带有一些 BOLDboldBOLD 和 ITALICitalicITALIC BOTHstylesBOTH。

总结:修改上述表达式以使用您喜欢的任何标签;只要您使用对称的结束标签,样式就可以很好地解析。

于 2013-08-19T07:26:54.793 回答
0

你说的不是JSON吗?有许多可用的 JSON 解析库。检查它们或清楚地发布您的要求。很明显,我的意思是您想要完成它的语言/平台,以及出于什么目的(只是为了得到一个想法)。

于 2013-08-19T07:22:51.930 回答