7

文字列を取得して半分に分割したい状況にあり、単語を尊重して、this string hereに分割されないようにします。this str ing hereむしろ、 に分割されthis string hereます。

最初のステップは、スペースに基づいて文字列を配列に分割し、それらの断片に基づいて長さを計算することだと思いますが、私の試みでは、長い文字列が誤って分割されてしまいます。

4

7 に答える 7

18

中央の前後の最初のスペースを探し、中央に最も近いスペースを選択します。

例:

var s = "This is a long string";

var middle = Math.floor(s.length / 2);
var before = s.lastIndexOf(' ', middle);
var after = s.indexOf(' ', middle + 1);

if (middle - before < after - middle) {
    middle = before;
} else {
    middle = after;
}

var s1 = s.substr(0, middle);
var s2 = s.substr(middle + 1);

デモ: http://jsfiddle.net/7RNBu/

(このコードは、実際には中央の両側にスペースがあることを前提としています。また、beforeおよびafterであるのチェックも追加します-1。)

編集:

ノードで説明したチェックは、次のように正しく実行されます。

if (before == -1 || (after != -1 && middle - before >= after - middle)) {
    middle = after;
} else {
    middle = before;
}

これは、テキストを編集してすぐに結果を確認できるフィドルです: http://jsfiddle.net/Guffa/7RNBu/11/

于 2013-08-06T18:21:44.380 に答える
3

これをコメントとして残したかったのですが、十分な担当者ポイントがありません。indexOf メソッドを使用するときに「-1」をチェックしないため、現在のトップ ソリューションは簡単に失敗します。このフィドルを参照してください:

http://jsfiddle.net/7RNBu/7/

var s = "This is a long strinjjjjjjjjjjjjjjjjg";
var middle = Math.floor(s.length / 2);
var before = s.lastIndexOf(' ', middle);
var after = s.indexOf(' ', middle + 1);

if (middle - before < after - middle) {
    middle = before;
} else {
    middle = after;
}

var s1 = s.substr(0, middle);
var s2 = s.substr(middle + 1);
于 2014-01-10T01:27:24.293 に答える
0

これにより、単語数に基づいて文字列が分割されます (文字数ではなく、長い単語と短い単語の配置に応じて、各半分の正確な長さがまったく異なる可能性があります)。

var s = "This is a string of filler text";

var pieces = s.split(" "),
    firstHalfLength = Math.round(pieces.length/2),
    str1 = "",
    str2 = "";

for (var i = 0; i < firstHalfLength; i++){
    str1 += (i!=0?" ":"") + pieces[i];
}
for (var i = firstHalfLength; i < pieces.length; i++){
    str2 += (i!=firstHalfLength?" ":"") + pieces[i];
}

document.write(s);
document.write("<br />"+str1);
document.write("<br />"+str2);

// Output
This is a string of filler text
This is a string
of filler text

http://jsfiddle.net/daCrosby/7RNBu/2/

于 2013-08-06T19:44:59.490 に答える
0

最初は、1 つずれているエラーがあると思いましたが、最終的には解決しました。 これが実際の例です。

ここで、使用されるロジックを分解します。

var calculate = function(initialString) {
  var halfwayPoint = Math.floor(initialString.length / 2);
  var strArray = initialString.split(' ');
  // Caluclate halfway point, then break string into words

  var wordFlag;  // Will be split point
  var charCount = 0;
  _.each( strArray, function(word, strArrayIndex) {
    if (wordFlag) return false;
    // If we have the location, exit

    // If charCount is before the halfway point
    // and the end of word is after halfway point
    // Then set the flag
    // We add strArrayIndex to the word length to include spaces
    if (charCount <= halfwayPoint && 
      ((charCount + word.length + strArrayIndex) >= halfwayPoint) ) {
      wordFlag = strArrayIndex;
      return false;
    }

    // Increase charCount to be length at the end of this word
    charCount += (word.length);
  });

  if (!wordFlag) return null;

  // Split the word array by the flag we figured out earlier
  var lineOneArray = strArray.slice(0, (wordFlag + 1));
  var lineTwoArray = strArray.slice(wordFlag + 1);


  // We now join the word arrays into a string, stripping beginning and ending spaces.
  var stOne = (lineOneArray.join(' ')).replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  var stTwo = (lineTwoArray.join(' ')).replace(/^\s\s*/, '').replace(/\s\s*$/, '');

  // Finally return the split strings as an array.
  return [stOne, stTwo];
};

誰かが私の論理に穴を見つけたら、私に知らせてください! ただし、これはほとんどの場合に機能すると確信しています。

2 番目の文字列を最初の文字列よりも長くしたい場合 (つまり、中間の単語の後ではなく前に改行を入れたい場合)、wordFlag に +1 を追加しないでください。

于 2013-08-06T18:09:59.910 に答える
0

改行、タブ、およびスペースも気にする場合があるため、次のような正規表現を使用します。

var s = "this string here";
var idx = s.length / 2;


while (idx < s.length && s[idx].match(/\s/) == null)
    idx++;

var s1 = s.substring(0, idx);
var s2 = s.substring(idx);

document.getElementById("s1").innerText = s1;
document.getElementById("s2").innerText = s2;

このフィドルを参照してください: http://jsfiddle.net/nS6Bj/5/

于 2013-08-06T18:33:38.753 に答える