如何将文本按指定的字符行长度进行自动换行?

huangapple go评论83阅读模式
英文:

How to word-wrap text to a given row length in characters?

问题

我想将文本进行换行,生成一个包含最多N个字符的行(短语/行)。如果一个单词比最大行长度长,那么该单词应该被截断为该长度。

编辑:最大字符长度n永远不小于100个字符,我使用10只是为了向您展示我的代码工作不正常

问题是我的代码没有正常工作,如您所见。

期望的输出应该是:

["Wake has", "three", "meanings", "as a noun,", ...] // 每个行的长度分别为:8 - 5 - 8 - 10

英文:

I want to word-wrap text into an array of rows (phrases / lines) with max length of N characters. If a word is bigger than the max row length the word should be cut to the length.

Edit: max length of n characters is never less than 100 chars, I used 10 to show you my code is not working properly

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const sentence =`Wake has three meanings as a noun, and, yes, just about as many meanings as a verb! So get set. To wake is come out of sleep, a verb you&#39;ll recognize from &quot;Wake up! You&#39;re asleep at the wheel!&quot; You can wake feelings, as well as the people who are having them. The wake before the funeral caused Mike to wake from his depression and decide to live life to the fullest. His first act was to water ski; he eventually mastered staying upright while crossing the wake of the boat that was towing him.`

// shorten with max characters of 10
console.log(shorten(sentence, 10));

function shorten(str, maxLen) {

  if(str.length &lt;= maxLen) return [str];
  let max, min = 0, i = 1;
  const result = [];
	while (maxLen * i &lt; str.length) {
    max = str.lastIndexOf(&#39; &#39;, maxLen * i);
  	result.push(str.substr(min, max));
    min = max + 1;
    i++;
	}
  return result;
 
}

<!-- end snippet -->

The issue is my code dos't work correctly as you see.

The desired out put would be:

[&quot;Wake has&quot;, &quot;three&quot;, &quot;meanings&quot;, &quot;as a noun,&quot;, ...]  // each one has length of : 8 - 5 - 8 - 10

答案1

得分: 2

You can use regex (?=\S).{0,99}\S(?!\S)|\S{100} in conjunction with .matchAll to find desired blocks of symbols (for parameter equal 100).

Here regex matches:

  • (?=\S).{0,99}\S(?!\S) block of one to a hundred symbols, that begin and end with non-whitespace symbols, and followed by either whitespace or end of the line:
    • (?=\S) lookaround that checks the first symbol to be non-whitespace,
    • .{0,99} between 0 and 99 of any symbols, except newlines,
    • \S matches the last symbol to be non-whitespace,
    • (?!\S) checks that the match is followed by a whitespace symbol (to prevent wrapping in the middle of the word)
  • \S{100} a hundred consecutive non-whitespace symbols: for cases of very long words that span over the maximum expected line length.

Example of code:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const sentence =Wake has three meanings as a noun, and, yes, just about as many meanings as a verb! So get set. To wake is to come out of sleep, a verb you'll recognize from "Wake up! You're asleep at the wheel!" You can wake feelings, as well as the people who are having them. The wake before the funeral caused Mike to wake from his depression and decide to live life to the fullest. His first act was to water ski; he eventually mastered staying upright while crossing the wake of the boat that was towing him.

console.log(wrapLines(sentence, 100));

function wrapLines(str, maxLen){
let reg = new RegExp('(?=\S).{0,'+(maxLen-1)+'}\S(?!\S)|\S{'+maxLen+'}', 'gm')
console.log(reg)
return Array.from(str.matchAll(reg), (m) => m[0]);
}
<!-- end snippet -->

英文:

You can use regex (?=\S).{0,99}\S(?!\S)|\S{100} in conjunction with .matchAll to find desired blocks of symbols (for parameter equal 100).

Here regex matches:

  • (?=\S).{0,99}\S(?!\S) block of one to hundred symbols, that begin and end with non-whitespace symbols, and followed by either whitespace or end of line:
    • (?=\S) lookaround that checks first symbol to be non-whitespace,
    • .{0,99} between 0 and 99 of any symbols, except newlines,
    • \S matches last symbol to be non-whitespace,
    • (?!\S) checks that match is followed by whitespace symbol (to prevent wrapping in the middle of the word)
  • \S{100} a hundred of consequent non-whitespace symbols: for cases of very long words, that span over maximum expected line length.

Example of code:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const sentence =Wake has three meanings as a noun, and, yes, just about as many meanings as a verb! So get set. To wake is come out of sleep, a verb you&#39;ll recognize from &quot;Wake up! You&#39;re asleep at the wheel!&quot; You can wake feelings, as well as the people who are having them. The wake before the funeral caused Mike to wake from his depression and decide to live life to the fullest. His first act was to water ski; he eventually mastered staying upright while crossing the wake of the boat that was towing him.

console.log(wrapLines(sentence, 100));

function wrapLines(str, maxLen){
    let reg = new RegExp(&#39;(?=\\S).{0,&#39;+(maxLen-1)+&#39;}\\S(?!\\S)|\\S{&#39;+maxLen+&#39;}&#39;, &#39;gm&#39;)
    console.log(reg)
    return Array.from(str.matchAll(reg), (m) =&gt; m[0]);
}

<!-- end snippet -->

答案2

得分: 1

把它改成:

const sentence = `“Wake”作为名词有三个意思,是的,作为动词它也有几乎一样多的意思!所以做好准备。醒来是从睡梦中醒来,这是一个你会从“醒来!你在开车时睡着了!”这句话中认出的动词。你可以唤醒情感,也可以唤醒正在经历情感的人。葬礼前的守夜使迈克从抑郁中醒来,决定充分地生活。他的第一个行动是滑水;他最终掌握了在被拖曳的船的航迹上保持直立。”`;

console.log(shorten(sentence, 10));

function shorten(str, maxLen) {
  if (str.length <= maxLen) return [str];
  
  const result = [];
  let startIndex = 0;
  let endIndex = maxLen;
  
  while (endIndex < str.length) {
    while (str[endIndex] !== ' ' && endIndex > startIndex) {
      endIndex--;
    }
    
    result.push(str.substring(startIndex, endIndex));
    startIndex = endIndex + 1;
    endIndex = startIndex + maxLen;
  }
  
  result.push(str.substring(startIndex));
  
  return result;
}
英文:

Change it to,

const sentence = `Wake has three meanings as a noun, and, yes, just about as many meanings as a verb! So get set. To wake is come out of sleep, a verb you&#39;ll recognize from &quot;Wake up! You&#39;re asleep at the wheel!&quot; You can wake feelings, as well as the people who are having them. The wake before the funeral caused Mike to wake from his depression and decide to live life to the fullest. His first act was to water ski; he eventually mastered staying upright while crossing the wake of the boat that was towing him.`;

console.log(shorten(sentence, 10));

function shorten(str, maxLen) {
  if (str.length &lt;= maxLen) return [str];
  
  const result = [];
  let startIndex = 0;
  let endIndex = maxLen;
  
  while (endIndex &lt; str.length) {
    while (str[endIndex] !== &#39; &#39; &amp;&amp; endIndex &gt; startIndex) {
      endIndex--;
    }
    
    result.push(str.substring(startIndex, endIndex));
    startIndex = endIndex + 1;
    endIndex = startIndex + maxLen;
  }
  
  result.push(str.substring(startIndex));
  
  return result;
}

</details>



# 答案3
**得分**: 1

根据我理解,任务是在等宽字体中对文本进行换行处理。以下是翻译好的部分:

```javascript
// shorten with max characters of 10
console.log(shorten(sentence, 10).map(str => str + ': ' + str.length));

function shorten(str, maxLen) {

    const phrases = [];
    let phrase = '';
    let word = '';

    const addWord = () => {
        if (word) {
            phrase.length + word.length >= maxLen && addPhrase();
            phrase += (phrase ? ' ' : '') + word;
            word = '';
        }
    };

    const addPhrase = () => {
        if (phrase) {
            phrases.push(phrase.length > maxLen ? phrase.substring(0, maxLen) : phrase);
            phrase = '';
        }
    };

    for (let i = 0; i < str.length; i++) {
        const c = str[i];
        c === ' ' ? addWord() : word += c;
    }

    addWord();
    addPhrase();

    return phrases;
}

以上是代码部分的翻译。

英文:

As I understand the task is to word-wrap text in a monospaced font.
Somehow that works:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const sentence = `Some-long-string-should-be-cut-to-10 Wake has three         meanings as a noun, and, yes, just about as many meanings as a verb! So get set. To wake is come out of sleep, a verb you&#39;ll recognize from &quot;Wake up! You&#39;re asleep at the wheel!&quot; You can wake feelings, as well as the people who are having them. The wake before the funeral caused Mike to wake from his depression and decide to live life to the fullest. His first act was to water ski; he eventually mastered staying upright while crossing the wake of the boat that was towing him.`

// shorten with max characters of 10
console.log(shorten(sentence, 10).map(str =&gt; str + &#39;: &#39; + str.length));

function shorten(str, maxLen) {

    const phrases = [];
    let phrase = &#39;&#39;;
    let word = &#39;&#39;;

    const addWord = () =&gt; {
        if(word){
            phrase.length + word.length &gt;= maxLen &amp;&amp; addPhrase();
            phrase += (phrase ? &#39; &#39; : &#39;&#39;) + word;
            word = &#39;&#39;;
        }
    };

    const addPhrase = () =&gt; {
        if(phrase){
            phrases.push(phrase.length &gt; maxLen ? phrase.substring(0, maxLen) : phrase);
            phrase = &#39;&#39;;
        }
    };

    for (let i = 0; i &lt; str.length; i++) {
        const c = str[i];
        c === &#39; &#39; ? addWord() : word += c;
    }

    addWord();
    addPhrase();

    return phrases;
}

<!-- end snippet -->

答案4

得分: 1

你可以这样做,如果你没有大量的文本,这可能是可行的:

function textSplitter(text, maxLength){
    var currentPos = 0;
    var result = [];
    while(currentPos < text.length){
        const probe = text.substring(currentPos, currentPos+maxLength); // 取最大长度
        const lastSpace = probe.lastIndexOf(" "); // 回溯到最后一个空格
   
        const item = probe.substring(0, lastSpace); // 取你想要的部分
        result.push(item); // 存储它
        currentPos += item.length + 1; // 1 是空格
    }

    return result;
}

这是未经测试的代码,我预计在某些地方需要+1或-1,但这只是一个示例。
(如果有人想调整并修复它,请随意这样做)。

英文:

You could do this, if you dont have huge amounts of text this might be doable:

function textSplitter(text, maxLength){
    var currentPos = 0;
    var result = [];
    while(currentPos &lt; text.length){
        const probe = text.substring(currentPos, currentPos+maxLength); // take max length
        const lastSpace = probe.lastIndexOf(&quot; &quot;); // track back to last space
   
        const item = probe.substring(0, lastSpace); // take what you want
        result.push(item); // store it
        currentPos += item.length + 1; // 1 is the space
    }

    return result;
}

This is untested code, and I expect that you need a +1 or -1 at some spots, but this is an example.
(If someone wants to tweak it and fix it, feel free to do so).

huangapple
  • 本文由 发表于 2023年6月8日 22:54:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433136.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定