【问题标题】:find '*' , '**' and '`' from string and replace with <strong></strong> and <code></cod in javascript, Typescript从字符串中查找 '*' 、 '**' 和 '`' 并在 javascript、Typescript 中替换为 <strong></strong> 和 <code></cod
【发布时间】:2019-12-12 14:47:26
【问题描述】:

我们需要处理一个“字符串”并用&lt;strong&gt;&lt;/strong&gt;包围'*'和'**'之间的所有文本,类似地用&lt;code&gt; &lt;/code&gt;包围backTic之间的文本。现在我已经编写了逻辑,它也可以正常工作,但我确信,必须有更好的方法,因为对于这个简单的字符串处理任务来说代码太多了。以下是我的代码。感谢任何建议。

输入 = "*within single star* and **within double start** and this is `backtick string`"

输出 = "&lt;strong&gt;within single star&lt;/strong&gt; and &lt;strong&gt;within double start&lt;/strong&gt; and this is &lt;code&gt;backtick string&lt;/code&gt;"

transform(data: any) {
        if (data) {
            const processDblStar = (input) => {
                const regExforDoubleStar = /(\*\*)+/gi;
                let i = 0;
                const result = input.replace(regExforDoubleStar, (match, matchedStr, offset) => {
                    i++;
                    return i % 2 === 0 ? '</strong>' : '<strong>';
                });
                return result;
            };

            const processSingleStar = (input) => {
                const regExforSingleStar = /(\*)+/gi;
                let i = 0;
                const result = input.replace(regExforSingleStar, (match, matchedStr, offset) => {
                    i++;
                    return i % 2 === 0 ? '</strong>' : '<strong>';
                });
                return result;
            };

            const processBackTick = (input) => {
                const regExforBackTick = /(\`)+/gi;
                let i = 0;
                const result = input.replace(regExforBackTick, (match, matchedStr, offset) => {
                    i++;
                    return i % 2 === 0 ? '</code>' : '<code>';
                });
                return result;
            };

            const processPipeline = (functions) => (inputStr) => functions.reduce((result, fn) => fn(result), inputStr);

            const funcArr: Function[] = [];
            if (data.indexOf('`') >= 0) {
                funcArr.push(processBackTick);
            }
            if (data.indexOf('*') >= 0) {
                funcArr.push(processSingleStar);
            }
            if (data.indexOf('**') >= 0) {
                funcArr.push(processDblStar);
            }

            processPipeline(funcArr)(data);
        }
    }

【问题讨论】:

  • 动态 html 有点棘手,我会研究作为 JS 一部分的 render 函数,这似乎是一种更惯用的方式,然后从标准函数返回 html
  • 看来你想实现 Markdown 语法。为什么不使用现有的 Markdown 解析器之一?
  • @Amadan 我没有使用 Markdown 解析器,但正如你指出的那样,我会调查它。感谢您的意见。
  • 您可以按照@Amadan 的建议使用 Markdown,只启用您描述的功能子集:github.com/markedjs/marked/pull/660

标签: javascript typescript ecmascript-6 ecmascript-2016


【解决方案1】:

您可以使用正则表达式对*** 之间的所有文本进行分组。使用该组,您可以通过使用$1 在替换字符串中使用它。我们也可以对反引号做同样的事情,但是,将匹配的组包围在&lt;code&gt;&lt;/code&gt; 标签中。

const str = '*within single star* and **within double start** and this is `backtick string`';

const proccessPipeline = s =>
   s.replace(/\*{1,2}(.*?)\*{1,2}/g, '<strong>$1</strong>')
    .replace(/`(.*?)`/g, '<code>$1</code>');

const res = proccessPipeline(str);
console.log(res);
document.body.innerHTML = res;

【讨论】:

  • 这也将允许*mismatched** 星号。您可以使用反向引用,但我不确定支持有多好。
  • 它应该根据是单星号还是双星号来做两种不同的事情。
  • @hugo 如果它应该做两件不同的事情,那就是当你做*foo***foo** 时。但是,我希望*foo****foo* 要么是语法错误,要么不会触及额外的星号。我会改用 /(\*{1,2})(.*?)\1/,就像 mpen 建议的那样,或者分成两个不同的正则表达式(我知道的所有正则表达式引擎都普遍支持反向引用。)
  • 它是写给答案的作者的。当然,您指出的内容更令人担忧,并且使解决方案不可行,但是当我发表评论时,您的信息还没有出现。
  • @Akash 嗨,我相信有一种方法可以做到 *mismatched** 不会被解析,正如 mpen 建议的那样,我们将使用反向引用。但是,我不是正则表达式专家,所以我不能 100% 确定如何做到这一点。
【解决方案2】:

这不是最好的方法。但短代码。

var converter = new showdown.Converter();
var input = "*within single star* and **within double start** and this is `backtick string`";
var output = converter.makeHtml(input);
output = "\"" + output + "\""
output = output.replace(/<p>/g, "")
output = output.replace(/<\/p>/g, "")
output = output.replace(/<em>/g, "<strong>")
output = output.replace(/<\/em>/g, "</strong>")
console.log(output)
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/showdown/1.9.0/showdown.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 您正在使用@Amadan 建议的降价解析器。感谢您提供此解决方案。我会仔细检查这个降价解析器,因为我过去没有使用过它们。为您的努力 +1。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多