重新塑形字符串,每N个字符插入“\n”

5
使用JavaScript函数,我试图在用户提供的每N个字符处在字符串中插入一个换行符。
就像这样:function("blabla", 3)将输出"bla\nbla\n"。 我搜索了很多答案,最终得到了一个正则表达式来实现这一点,唯一的问题是,我需要用户对此进行输入,因此我需要在这个正则表达式上添加一个变量。
以下是代码:
function reshapeString(string, num) {
    var regex = new RegExp("/(.{" + num + "})/g");
    return string.replace(regex,"$1\n");
}

reshapeString("blablabla", 3);

这目前无法工作。我尝试转义 '/' 字符,但在某个点上搞砸了,我不知道出了什么问题。

我缺少什么?还有其他解决重新格式化此字符串的问题的方法吗?

4个回答

4

在正则表达式构造函数中,您需要一个字符串,但不需要包含/,并且可以使用$&表示找到的字符串来省略组。

function reshapeString(string, num) {
    var regex = new RegExp(".{" + num + "}", "g");
    return string.replace(regex,"$&\n");
}

console.log(reshapeString("blablabla", 3));


如果reshapeString("abc ab abc")有类似的参数怎么办?我想要得到这样的输出:- abc \n ab \n abc - Nirmal Patel
@NirmalPatel,问题和答案使用相同的长度来分割,而不是可变长度的部分。 - Nina Scholz

3
如何用一行代码实现?
const reshapeString = (str,N) => str.split('').reduce((o,c,i) => o+(!i || i%N?'':'\n')+c, '')

解释:

  • 首先,我们将字符串拆分为字符数组。
  • 现在,我们使用 reduce() 语句遍历每个元素并缩减为单个值(即您要查找的最终字符串!)
  • 现在,当索引不是 N 的倍数时,i%N 应该给出非零值(即 一个真值),因此我们只需将当前字符添加到累加器变量 o 中。
  • 如果 i%N 实际上是 0 (则其值为 假值),我们将追加:
    • o(即迄今为止的字符串)+
    • \n(即第 N 个间隔处的附加字符)+
    • c(当前字符)
  • 注意:我们还有一个 !i 检查,用于忽略第一个字符,因为这可能被视为意外行为

基准测试

正则表达式构建和替换还需要重新构建字符串并创建 FSA 以进行跟随。对于小于 1000 的字符串,这应该会更慢。

测试:

(_ => {
    const reshapeString_AP = (str,N) => str.split('').reduce((o,c,i) => o+(!i || i%N?'':'\n')+c, '')
    function reshapeString_Nina(string, num) {
        var regex = new RegExp(".{" + num + "}", "g");
        return string.replace(regex,"$&\n");
    }

    const payload = 'a'.repeat(100)
    console.time('AP');
    reshapeString_AP(payload, 4)
    console.timeEnd('AP');
    console.time('Nina');
    reshapeString_Nina(payload, 4)
    console.timeEnd('Nina');
})()

结果(3次运行):

AP: 0.080078125ms
Nina: 0.13916015625ms
---
AP: 0.057861328125ms
Nina: 0.119140625ms
---
AP: 0.070068359375ms
Nina: 0.116943359375ms

这是完美的答案(也是我正在打字中的)。:D - th3n3wguy
1
你打字比我快,很高兴看到有人像你这样思考,而不是使用愚蠢的正则表达式。 - th3n3wguy
能否帮我详细讲解一下?我是个真正的初学者。 - Platiplus
1
@Platiplus 我建议你接受下面 Nina 的答案,因为它回答了你实际的问题。我认为她的方法更快,因为正则表达式在低级别上运行,而不是通过 if 语句迭代数组并构建字符串。 - Toby
@Toby,这个回答为什么没有解决问题:“有没有其他方法来解决重新塑造这个字符串的问题?”关于字符串长度的观点很公正,但是在某些情况下,这种解决方案确实具有优势,并且无论字符串长度如何,都可以被认为是一种有效的方法。 - AP.
显示剩余9条评论

1

公共静态字符串重塑(int n,字符串str){

    StringBuilder sb = new StringBuilder();

    char[] c = str.replaceAll(" " , "").toCharArray();
        int count =0;
        for (int i = 0; i < c.length; i++) {
            if(count != n){
                sb.append(c[i]);
                count++;
             }else {
                count = 1;
                sb.append("\n").append(c[i]);
            }
        }

    return sb.toString();
}

你的回答可以通过提供更多支持信息来改进。请编辑以添加进一步的细节,例如引用或文档,以便他人可以确认你的答案是正确的。您可以在帮助中心中找到有关如何编写良好答案的更多信息。 - Community

0

字符串是不可变的,所以无论你做什么都必须创建一个新的字符串。最好一开始就开始创建它。

var newLineForEach = (n,s) => s && `${s.slice(0,n)}\n${newLineForEach(n,s.slice(n))}`,
    result = newLineForEach(3,"blablabla");
console.log(result);

我的测试表明这是迄今为止最快的。100K次迭代结果为Nina的1260毫秒,AP的103毫秒和Redu的33毫秒。被接受的答案非常低效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接