首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NodeJS字符串替换多组xml标记中的性能换行符

NodeJS字符串替换多组xml标记中的性能换行符
EN

Stack Overflow用户
提问于 2021-04-03 02:08:29
回答 1查看 94关注 0票数 2

我有一个非常大的字符串,我正在对它运行一个替换循环。字符串的长度是15967025字符(是的,它很大)。循环,每次迭代耗时4-5秒。

我使用while循环遍历字符串,并用一个相当复杂的正则表达式替换它-最终目标是用<text:line-break/>替换匹配text:p标记内的所有换行符

代码语言:javascript
复制
const undefinds = /(undefined)/g;
const nulls = /(<[A-z:\s-="\d]*>)(null)(<\/[A-z:\s-="\d]*>)/gi;
const nullsReplace = '$1None$3';

const regexToReplace = /(<text:p ....>)(...\n...)(</text:p>)/g;
const replaceWith = '$1<text:line-break/>$2';

export function cleanOutput(output) {

    while (output.match(regexToReplace)) {
        output = output.replace(regexToReplace, replaceWith);
    }

    return output;
}

我看到的问题是,这个循环每次运行都需要大约4-5秒。对于这种长度的字符串,这正常吗?有没有更好的方法来做这件事?

**编辑1:**

我为要替换的模式添加了一个更详细的示例。我不认为我可以使用/g标志,因为我在一些匹配的标记中进行多个替换。

下面是我正在做的完整示例,目标是用<text:line-break />替换<text:p>元素中的换行符。但我希望保留包装文本,即xml。

代码语言:javascript
复制
const newLines = /(<text:p[^/>]*?>[\s\S]*?)(\r\n|\r|\n)+?([\s\S]*?<\/text:p>)/g;
const newLineReplace = '$1<text:line-break/>$3';

export function cleanOutput(output) {
    output = output.replace(undefinds, 'None')
        .replace(nulls, nullsReplace);

    while (output.match(newLines)) {
        output = output.replace(newLines, newLineReplace);
    }

    return output;
}

编辑2:

我添加了缺少的未定义/空值替换。很抱歉没有包括这一点。不过,这种缓慢肯定发生在while循环中--每次迭代之间确实需要大约4-5秒。

编辑3:

下面是一个可以尝试的示例测试用例:

代码语言:javascript
复制
<text:p>some text\n\nother text\n</text:p>

预期输出:

代码语言:javascript
复制
<text:p>some text<text:line-break/><text:line-break/>other text<text:line-break/></text:p>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-13 18:59:39

从正则表达式的角度来看,匹配两个字符串之间的所有子字符串,然后只替换匹配中某个其他模式的所有匹配项,而不是试图找出一个通用模式来查找两个字符串之间的所有模式匹配项,这样更易于维护。

因此,您需要匹配<text:p></text:p>之间的所有子字符串,并替换所有出现的换行符(让我们将换行符定义为CR、LF或CRLF字符序列):

代码语言:javascript
复制
let text = `<text:p>some text\n\nother text\n</text:p>`;
const regex = /(<text:p(?:\s[^>]*)?>)([^<]*(?:<(?!\/text:p>)[^<]*)*)(<\/text:p>)/g;
text = text.replace(regex, (_, open, content, close) =>
  `${open}${content.replace(/\r\n?|\n/g, '<text:line-break/>')}${close}`);
console.log(text);

(<text:p(?:\s[^>]*)?>)([^<]*(?:<(?!\/text:p>)[^<]*)*)(<\/text:p>) (demo)是一种展开的(=更有效的) (<text:p(?:\s[^>]*)?>)([\w\W]*?)(<\/text:p>)模式(demo),它简单地匹配<text:p...>标记,然后匹配任何文本,直到第一次出现</text:p>

\r\n?|\n模式与带有\r\n?的CRLF或CR模式和以\n结尾的LF匹配。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66923473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档