简体   繁体   English

拆分文本,每隔n个字符添加一个新行,处理空格

[英]Split a text to add a new line every n characters taking care of spaces

Common problem when writing text for alert and confirm dialogs: number of characters to type before adding a newline character. 为警报和确认对话框编写文本时的常见问题:在添加换行符之前要键入的字符数。 Some browsers auto-break at one point, others at others. 有些浏览器会在某个时刻自动中断,其他浏览器会在其他浏 So you are left guessing. 所以你要猜测。 Useful snippet is a Javascript function that takes as input the alert or confirm dialog's intended text and a char length, then returns the same input string only with new line chars added at the positions with spaces closest to the char length passed in. That way, words are not broken up mid-way. 有用的片段是一个Javascript函数,它将警报或确认对话框的预期文本和字符长度作为输入,然后返回相同的输入字符串,只有在最接近传入的字符长度的空格位置添加新的行字符。这样,单词在中途没有被打破。

Example: 例:
1. Assign a var to a string of text you want to use for the alert or confirm dialog box, eg.: 1.将var分配给要用于警报或确认对话框的文本字符串,例如:
var a = "My dog has fleas the quick brown fox jumps over the lazy dog etc"; var a =“我的狗跳蚤快速的棕色狐狸跳过懒狗等”;
2. Run the text through the function, for example: 2.通过该函数运行文本,例如:
a = breakLines(a); a = breakLines(a); // Default, break every 50 chars //默认,每50个字符中断一次
or 要么
a = breakLines(a, 20); a = breakLines(a,20); // Break every 20 chars //打破每20个字符

Display the value of 'a' after running it through the function and you will see line breaks have been added at every place you specified at the space character closest to the character place you specified. 在通过函数运行后显示“a”的值,您将看到在最近指定的字符位置的空格字符处指定的每个位置都添加了换行符。 For example if you specified 20, 'a' would be converted to the following: 例如,如果您指定了20,则'a'将转换为以下内容:

'My dog has fleas\\nthe quick brown fox\\njumps over the lazy\\ndog etc' '我的狗有跳蚤\\快速的棕色狐狸\\ njumps懒惰\\ n狗等'

For each line in the string (a line is a portion of the string ending in a new line character), the line is trimmed of whitespace on both sides. 对于字符串中的每一行(一行是以新行字符结尾的字符串的一部分),该行将在两侧修剪为空白。 The code snippet below uses the jQuery $.trim() function to do this but there are other ways to do so without using the jQuery library, such as with regexp. 下面的代码片段使用jQuery $ .trim()函数来执行此操作,但还有其他方法可以在不使用jQuery库的情况下执行此操作,例如使用regexp。 Just modify the code as you want to to use alternate means. 只需修改代码即可使用其他方法。

This leads to my question: Aside from doing what I want to do the way I have done it as shown below, is there an easier more compact way of doing it, something that for example can leverage regexp? 这导致了我的问题:除了做我想做的事情,如下所示我做的方式,是否有一种更简单的方式来做,例如可以利用正则表达式? Any takers? 任何接受者?

function breakLines(text, linelength)
{
 var linebreak = '\n';
 var counter = 0;
 var line = '';
 var returntext = '';
 var bMatchFound = false;
 var linelen = 50; // 50 characters per line is default

 if(linelength)
 {
  linelen = linelength;
 }

 if(!text){ return '';}
 if(text.length < linelen+1) { return $.trim(text);}

 while(counter < text.length)
 {
  line = text.substr(counter,linelen);
  bMatchFound = false;
  if (line.length == linelen)
  {
   for(var i=line.length;i > -1;i--)
   {
    if(line.substr(i,1)==' ')
    {
     counter += line.substr(0,i).length;
     line = $.trim(line.substr(0,i)) + linebreak;
     returntext += line;
     bMatchFound = true;
     break;
    }
   }

   if(!bMatchFound)
   {
    counter+=line.length;
    line = $.trim(line) + linebreak;
    returntext += line;
   }
  }
  else
  {
   returntext += $.trim(line);
   break; // We're breaking out of the the while(), not the for()
  }
 }

 return returntext;
}

Maybe ? 也许 ?

function breadLines( str, len )
{
    var len = len || 50, i, j, lines, count, lineBreak = '\n', out = [];

    if ( str.length < len )
        return str;

    lines = str.split(/\s+/);

    for ( i=0, j=0, count=lines.length; i<count; i++ )
    {
        if ( ( out[j] + lines[i] ).length > len )
            j++, out.push("");

        out[j] += lines[i];
    }

    return out.join(lineBreak);
}

Here is a commented solution that uses recursion (23 lines without comments vs 38 for yours): 是一个使用递归的评论解决方案(23行没有评论,38为你的):

function explode(text, max) {
    // clean the text
    text = text.replace(/  +/g, " ").replace(/^ /, "").replace(/ $/, "");
    // return empty string if text is undefined
    if (typeof text === "undefined") return "";
    // if max hasn't been defined, max = 50
    if (typeof max === "undefined") max = 50;
    // return the initial text if already less than max
    if (text.length <= max) return text;
    // get the first part of the text
    var exploded = text.substring(0, max);
    // get the next part of the text
    text = text.substring(max);
    // if next part doesn't start with a space
    if (text.charAt(0) !== " ") {
        // while the first part doesn't end with a space && the first part still has at least one char
        while (exploded.charAt(exploded.length - 1) !== " " && exploded.length > 0) {
            // add the last char of the first part at the beginning of the next part
            text = exploded.charAt(exploded.length - 1) + text;
            // remove the last char of the first part
            exploded = exploded.substring(0, exploded.length - 1);
        }
        // if the first part has been emptied (case of a text bigger than max without any space)
        if (exploded.length == 0) {
            // re-explode the text without caring about spaces
            exploded = text.substring(0, max);
            text = text.substring(max);
        // if the first part isn't empty
        } else {
            // remove the last char of the first part, because it's a space
            exploded = exploded.substring(0, exploded.length - 1);
        }
    // if the next part starts with a space
    } else {
        // remove the first char of the next part
        text = text.substring(1);
    }
    // return the first part and the exploded next part, concatenated by \n
    return exploded + "\n" + explode(text);
}

Call: 呼叫:

var text = "               My dog has    fleas the quick brown fox jumps over the lazy dog etc";
var exploded = explode(text);
console.log(exploded);

Prints: 打印:

My dog has fleas the quick brown fox jumps over 我的狗跳蚤快速的棕色狐狸跳过

the lazy dog etc 懒狗等

Short version with no params validation 短版本没有参数验证

function explode(str, maxLength) {
    var buff = "";
    var numOfLines = Math.floor(str.length/maxLength);
    for(var i = 0; i<numOfLines+1; i++) {
        buff += str.substr(i*maxLength, maxLength); if(i !== numOfLines) { buff += "\n"; }
    }
    return buff;
}

This should do it: 这应该这样做:

function breaklines(str, n) {
    var lines = str.split(/\s+/), // explode on whitespaces
        n = +n || 50;
    var res = [];
    for (var i=0; i<lines.length; ) {
        for (var l = 0, line = []; l + lines[i].length <= n; i++) {
            l += 1 + lines[i].length;
            line.push(lines[i]);
        }
        res.push(line.join(" "));
    }
    return res.join("\n");
}

This function is recursive and a lot more simple. 这个函数是递归的,而且更简单。 It also deals with newlines already being in the text. 它还涉及文本中已有的换行符。 It's short and without loops. 它很短,没有循环。

function explode (text, max) {
        if (text == null) return '';
    if (text.length <= max) return text;
    const nextNewLine = /\n/.exec(text);

    const lineLength = nextNewLine ? nextNewLine.index: text.length;
    if (lineLength <=  max) {
        const line = text.substr(0, lineLength);
        const rest = text.substr(lineLength+1);
        return line + '\n'+  explode(rest, max);
    } else {
        let line = text.substr(0, max);
        let rest = text.substr(max);

        const res = (/([\s])[^\s]*$/.exec(line));
        if(res){ //
            line = text.substr(0, res.index);
            rest = text.substr(res.index+1);
        } else {
            line = line + "-";
        }
        return line + '\n'+  explode(rest, max);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM