ChatGPT解决这个技术问题 Extra ChatGPT

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

我发现了一个小函数,它从 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);
}

是否有可能实现我想要得到的?或者有没有办法简单地将文本区域按原样移动到画布中?

无法检测到由自动换行创建的换行符。如果文本区域包含通过点击 ENTER 创建的换行符,例如可以通过使用 \n 拆分来找到它们。
嗯,好吧,我将不得不重新制定策略。没有办法简单地将文本区域“移动”到画布中?
您应该将解决方案放入答案并接受它,而不是将其放入问题中。
拒绝接受 JavaScript 问题的 jQuery 答案。网络上到处都是-jquery每次我们进行 JavaScript 搜索的人。 😒︎
@John:正如 Jean-Paul 已经告诉你的那样,答案包括非 jQuery 解决方案和 jQuery 解决方案。

J
Jean-Paul

使用 .split()

var str = `你的跨越多行的文本` // 在 \n 或 \r 字符上分割字符串 var separateLines = str.split(/\r?\n|\r|\n/g); alert("总行数为:" + separateLines.length);

或使用 .match() 代替:

var str = `你的跨越多行的文本` // 在 \n 或 \r 字符上分割字符串 var separateLines = str.match(/[^\r\n]+/g); alert("总行数为:" + separateLines.length);

希望有帮助!


注意:要获取不带换行符的行内容,我们可以使用:str.split(/\r?\n/g); 适用于 \r\n\n
@S.Serp 很好的补充。
因使用 jQuery 回答 JavaScript 问题而被否决。依赖是弱点,只会减慢整体用户体验。
@John即使依赖项可能是弱点,但编程始终是简洁代码和良好性能之间的权衡。在这种情况下,可以通过两种方式回答这个问题:使用纯 JavaScript 和使用 jQuery。我给出了两者的答案。由 OP 决定遵循哪种实现。鉴于我在回答中展示了这两种方法,您的反对意见似乎没有必要。但每个人都有自己的看法。
@S.Serp str.split(/\r\n|\r|\n/g) 如果您也有 \r 只有换行符(如 I )
T
Tính Ngô Quang

在 JavaScript 中拆分字符串

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

或者

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

https://i.stack.imgur.com/vjU9C.png


我想第二个更适合这个目的(拆分)。不是吗?
是的,分裂更快
p
profimedica

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

用换行符分割字符串:

Result.split('\n');

在 JSON 中接收到的拆分字符串,其中特殊字符 \n 在 JSON.stringify(在 javascript 中)或 json.json_encode(在 PHP 中)期间替换为 \\n。因此,如果您的字符串包含在 AJAX 响应中,则已对其进行处理以进行传输。如果它没有被解码,它将把 \n 替换为 \\n** 并且你需要使用:

Result.split('\\n');

https://i.stack.imgur.com/2b9MR.png


m
martin

这就是我用来将文本打印到画布上的方法。输入不是来自 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;
    }

A
Ann Zen

您可以使用 split() 函数在换行的基础上中断输入。

yourString.split("\n")

P
Peter Mortensen

您应该尝试检测第一行。

然后:

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

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


j
jacksondc

这是我 [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);
  }