将类似markdown的字符串解析为具有样式属性的文本片段数组

时间:2017-05-31 07:21:39

标签: javascript regex parsing markdown

我要将以下类似markdown的字符串解析为以下数据结构:

"The _big_ dog is *nice*. _*Bang!*_ No_1."

[
  {text: "The "},
  {text: "big", underline: true},
  {text: " dog is "},
  {text: "nice", bold: true},
  {text: " "},
  {text: "Bang!", underline: true, bold: true},
  {text: " No_1."}
]

我说必须要有一些回溯。这可以用正则表达式实现。一个用于'下划线'部分可以是/\b_([^_]+)_\b/。我们只想匹配它们,当它周围有一个单词边界时,因此示例中的No_1不应该加下划线。事实证明,这对于*部分来说并不容易,所以我在下面使用另一种方法。但主要问题仍然是如何将事物联系在一起。

一个正则表达式匹配没有做到,带.exec的while循环看起来更有希望:下面的代码还没有正常工作,但是它可能会显示我目前对这个问题的看法:

function f (str) {
    const underline = "(?:^| )_([^_]+)_(?:$| )";
    const bold = "(?:^| )\\*([^*]+)\\*(?:$| )";
    const goOn = "([^_*]+)"

    const xs = [];
    const regex = new RegExp(underline + "|" + bold + "|" + goOn, 'g');

    while ((result = regex.exec(str)) !== null) {
        [all, u, b, g] = result;
        u && xs.push({ text: u, underline: true});
        b && xs.push({ text: b, bold: true});
        g && xs.push({ text: g});
    }

    return xs;
}

有人能给我一个如何正确解决这个问题的提示吗?

1 个答案:

答案 0 :(得分:1)

试试这个:



var input = "The _big_ dog is *nice*. _*Bang!*_ No_1.";

function f(str) {
  var splittedStr = str.split(' ');
  var outputArr = [];
  for (var i = 0; i < splittedStr.length; i++) {
    var text = splittedStr[i];
    var outputArrRow = {
      text: text.replace(/\*?_?\*?\b/g, '').replace(/\b\*?_?\*?/g, '')
    };
    if ((text.match(/_/g) || []).length > 1) { // If more than two occurrences of _ in the text.
      outputArrRow.underline = true;
    }
    if ((text.match(/\*/g) || []).length > 1) { // If more than two occurrences of * in the text.
      outputArrRow.bold = true;
    }
    outputArr.push(outputArrRow);
  }
  return outputArr;
}

console.log(JSON.stringify(f(input)));
&#13;
&#13;
&#13;

它返回:

[
    {"text": "The"},
    {"text": "big", "underline": true},
    {"text": "dog"},
    {"text": "is"},
    {"text": "nice.", "bold": true},
    {"text": "Bang!", "underline": true, "bold": true},
    {"text": "No_1."}
]

这有点不完整,因为它不能完全处理多字斜体或粗体,但它确实满足您的标准。更新您的问题,如果您有任何其他标准没有通过,请告知我们。

(这不会返回{text: " "}元素,但我找不到何时返回或不返回此模式的模式