在JavaScript中拆分字符串并检测换行符

100

我发现了一个小函数,它可以从一个 textarea 中获取字符串并将其放入一个 canvas 元素中,并在行过长时换行。但是它不能检测到换行符。下面是它目前的功能和应该实现的功能:

输入:

Hello

This is dummy text that could be inside the text area.
It will then get put into the canvas.

错误的输出:

Hello this is dummy text
that could be inside the
text area. It will then
get put into the canvas.

它应该输出什么:

Hello

This is dummy text that
could be inside the text
area. It will then get
put into the canvas.

这是我正在使用的函数:

function wrapText(context, text, x, y, maxWidth, lineHeight) {
    var words = text.split(' ');
    var line = '';

    for(var n = 0; n < words.length; n++) {
        var testLine = line + words[n] + ' ';
        var metrics = context.measureText(testLine);
        var testWidth = metrics.width;
        if (testWidth > maxWidth && n > 0) {
            context.fillText(line, x, y);
            line = words[n] + ' ';
            y += lineHeight;
        }
        else {
            line = testLine;
        }
    }
    context.fillText(line, x, y);
}

我是否能够达到我想要的目标?或者有没有一种方法可以将文本区域简单地移动到画布中?


1
自动文本换行创建的换行符无法被检测到。如果一个文本区域包含通过按“ENTER”键创建的换行符,则可以通过使用“\n”进行分割来找到它们。 - Teemu
嗯,好的,我需要重新制定策略。那么有没有简单地将文本区域移动到画布中的方法? - Dustin Silk
1
你应该把你的解决方案放到答案中并接受它,而不是放在问题中。 - jacksondc
2
因为在 JavaScript 问题中接受了一个 jQuery 的答案而被踩。网络上充满了每次进行 JavaScript 搜索时都必须加上“-jquery”的人。 - John
@John:正如Jean-Paul已经告诉你的那样,答案包括非jQuery解决方案和jQuery解决方案。 - user2357112
显示剩余2条评论
7个回答

149

使用.split()方法:

var str = `your text
           that spans
           multiple lines`

// Split the string on \n or \r characters
var separateLines = str.split(/\r?\n|\r|\n/g);

alert("Total number of separate lines is: " + separateLines.length);

或者使用.match()

var str = `your text
           that spans
           multiple lines`

// Split the string on \n or \r characters
var separateLines = str.match(/[^\r\n]+/g);
 
alert("Total number of separate lines is: " + separateLines.length);


54
注意:要获取没有换行符的行内容,我们可以使用 str.split(/\r?\n/g);,这适用于 \r\n\n - S.Serpooshan
1
@S.Serp 不错的补充。 - Jean-Paul
14
因回答一个涉及jQuery的JavaScript问题受到了负面评价。依赖项是软肋,只会拖慢整体用户体验。 - John
6
尽管依赖关系有可能成为弱点,但编程总是在简洁代码和良好性能之间做出平衡取舍。在这种情况下,问题可以用两种方式回答:使用纯JavaScript和使用jQuery。我针对两者都给出了答案。由于我的回答展示了这两种方法,你的负评似乎是不必要的。但每个人都有自己的意见。 - Jean-Paul
10
如果你也有像我一样只有\r的换行符,可以使用str.split(/\r\n|\r|\n/g) - Xenos
1
赞同Jean-Paul的评论。如果提供了JavaScript,则可以接受jQuery替代方案。但值得注意的是,即使有点过激,John也有一定道理。在许多情况下,要求使用jQuery并不理想(甚至不可能)。 - lilHar

52

在 JavaScript 中拆分字符串

var array = str.match(/[^\r\n]+/g);

或者

var array = str.split(/\r?\n/);

性能表现


1
我认为第二个更适合这个目的(分割)。不是吗? - Agostino
是的,分割得更快。 - Tính Ngô Quang
1
这是一个在线可用的工具吗? - Henrik

6

如果您需要从JSON中拆分字符串,则其中的 \n 特殊字符将替换为 \\n。

通过换行符拆分字符串:

Result.split('\n');

在JSON中接收到的字符串被分割,其中特殊字符\n已被替换为\\n(在JavaScript中使用JSON.stringify或在PHP中使用json.json_encode)。因此,如果您的字符串在AJAX响应中,它已经被处理过了。如果没有解码,则仍将使用\\n替换\n**,您需要使用:

Result.split('\\n');

请注意,您的浏览器调试工具可能无法像您预期的那样显示此方面,但是您可以看到按 \\n 分割后结果有两个条目,这正是我需要的情况:enter image description here

3

这是我用来在画布上打印文本的代码。输入不是来自于 textarea,而是来自于 input,我只按空格分割。虽然不完美,但对我的情况有效。它将行以数组形式返回:

splitTextToLines: function (text) {
        var idealSplit = 7,
            maxSplit = 20,
            lineCounter = 0,
            lineIndex = 0,
            lines = [""],
            ch, i;

        for (i = 0; i < text.length; i++) {
            ch = text[i];
            if ((lineCounter >= idealSplit && ch === " ") || lineCounter >= maxSplit) {
                ch = "";
                lineCounter = -1;
                lineIndex++;
                lines.push("");
            }
            lines[lineIndex] += ch;
            lineCounter++;
        }

        return lines;
    }

简单而优雅的解决方案 - Pawel

2
您可以使用split()函数,根据换行符将输入分解为多行。
yourString.split("\n")

1

你应该尝试检测第一行。

然后是:

if(n == 0){
  line = words[n]+"\n";
}

我不确定,但也许会有所帮助。


0

这是我[OP]使用的最终代码。可能不是最佳实践,但它起作用了。

function wrapText(context, text, x, y, maxWidth, lineHeight) {

    var breaks = text.split('\n');
    var newLines = "";
    for(var i = 0; i < breaks.length; i ++){
      newLines = newLines + breaks[i] + ' breakLine ';
    }

    var words = newLines.split(' ');
    var line = '';
    console.log(words);
    for(var n = 0; n < words.length; n++) {
      if(words[n] != 'breakLine'){
        var testLine = line + words[n] + ' ';
        var metrics = context.measureText(testLine);
        var testWidth = metrics.width;
        if (testWidth > maxWidth && n > 0) {
          context.fillText(line, x, y);
          line = words[n] + ' ';
          y += lineHeight;
        }
        else {
          line = testLine;
        }
      }else{
          context.fillText(line, x, y);
          line = '';
          y += lineHeight;
      }
    }
    context.fillText(line, x, y);
  }

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