Presented by Nishishi via Movable Type. Last Updated: 2016/10/14. 13:32:45.

すべての行頭に任意の文字列を追加する

既にある複数行の文字列に対して、各行の先頭に任意の文字列を自動追加したいことがあります。
例えば「●」記号を付加するとか、インデント用の空白を付加するとか。
ここでは例として、textarea要素内に入力された複数行の文字列に対して、その各行の先頭に、ユーザが入力した任意の文字列を追加する方法を紹介します。

テキストエリア内の各行頭に、指定した文字列を追加する (配列版)

各行に対して何らかの処理をする……という場合は、とりあえず1行ずつ配列に格納してから、その配列の各項目に対して、ループを使って望みの処理をするのが分かりやすい気がします。いちいち配列に展開したり、その後に結合したりする処理の分、若干面倒ではありますが。でも、分かりやすいですし、応用も利きやすい気はします。「元々配列に格納されているデータ」に対して処理をするなら、この方法の方が楽かも知れません。

◆ユーザの入力欄:



◆文字列リスト:

上記のサンプルでは、『上記の入力内容を、以下の各行の先頭に追加』ボタンを押すたびに、全行の先頭に指定の文字列(デフォルトでは「♪」記号)が挿入されます。

HTMLソースとJavaScriptソースは以下の通りです。

■HTMLソース:

◆ユーザの入力欄:<input type="text" size="30" id="sampleUserInput" value="♪" />
<input type="button" value="上記の入力内容を、以下の各行の先頭に追加" onclick="AddStringToEachLine();" />
◆文字列リスト:<textarea cols="30" rows="6" id="sampleTargetLines">リンゴ
みかん
バナナ</textarea>

最初にinput要素で入力欄を作り、次にinput要素でボタンを作り、最後にtextarea要素で結果表示欄を作っています。textarea要素にはダミーの文字列を3行ほど記述しています。なお、入力欄の装飾に関する記述は省略しています。
スクリプトから利用するため、ユーザが入力するためのinput要素には「sampleUserInput」というid名を、表示結果のtextarea要素には「sampleTargetLines」というid名を、それぞれ加えています。
ボタンがクリックされると、この後で作成する関数「AddStringToEachLine」が実行されます。

■JavaScriptソース:

function AddStringToEachLine() {
   // ユーザの入力得る
   var UserString = document.getElementById('sampleUserInput').value;
   // textareaの内容を改行で分割して配列に格納
   var nowArray = document.getElementById('sampleTargetLines').value.split("\n");
   // 各行を対象にして処理
   var retString = "";
   for( var i=0 ; i < nowArray.length ; i++ ) {
      if( !(i == nowArray.length-1 && nowArray[i].length == 0) ) {
         // 「最後の空行」以外なら処理(=先頭に文字列を追加)を行う
         retString += UserString + nowArray[i] + "\n";
      }
   }
   // 表示
   document.getElementById('sampleTargetLines').value = retString;
}

この例では、「textarea要素内に入力された文字列」を1行ずつ配列に格納して、その配列に対して1項目ずつ「行頭に指定文字列を追加する」処理を施しています。
上記のソースでは、具体的には以下のような処理をしています。

  1. id名「sampleUserInput」の要素のvalueプロパティの値を、変数「UserString」に格納。
  2. id名「sampleTargetLines」の要素のvalueプロパティの値を、改行「\n」で区切って分割し、配列「nowArray」へ格納。
  3. 配列内をループして、各行に対して処理(変数「UserString」の中身を各行頭に追加)。
    処理後の配列をすべて結合した文字列を、変数「retString」に格納。
    その際、
    • 最後の行が空行だった場合は、最後の行に対しては何も処理しない。
    • 最後の行以外や、最後の行でも空行ではない場合は、「現在の文字列」に変数「sampleUserInput」の内容を追加。(※元通り1項目1行で表示させるために、改行「\n」も付加。)
  4. id名「sampleTargetLines」の要素のvalueプロパティの値に、変数「retString」の中身を代入。

以上です。

若干ややこしいですが、『最後の行が空行だった場合は、最後の行に対しては何も処理しない』という点は、

if( !( i == nowArray.length-1 && nowArray[i].length == 0 ) ) {

というif文で実現しています。
これは、

  • 「i == nowArray.length-1」 :現在のループが「最後の行」を対象にしている場合
  • 「nowArray[i].length == 0」 :その配列項目に含まれる文字列が0文字(=空行)だった場合
  • 「 !( …… ) 」 :それらの否定

という意味です。
※配列「nowArray」内の項目数は「nowArray.length」で分かりますが、添え字は0から始まるので、「nowArray.length-1」が「最後の項目番号」になります。

実際に試してみると分かりますが、この条件指定がなければ、処理を実行するたびに余計な行がどんどん追加されてしまいます。(^_^;)

テキストエリア内の各行頭に、指定した文字列を追加する (正規表現版)

さて、textarea要素に入力された内容はプロパティ1つで一括取得が可能なので、replaceメソッドと正規表現を使うことでも同様の処理が実現できます。
1行の末尾には必ず「改行」があります。そして、「改行の直後」が「行の先頭」でもあります。つまり、正規表現を使って、この「改行文字」を「改行文字+任意の文字列」に置き換えることで、各行の先頭に任意の文字列を追加できます。
ただ、その方法だと「先頭行」だけは対象にならない上、「最後の行」の後に余計な処理を行ってしまいます。そのため、若干の工夫が必要です。

動作サンプルは以下の通りです。(動作は先ほどの配列版と同じです。)

◆ユーザの入力欄:



◆文字列リスト:

上記のサンプルでも、『上記の入力内容を、以下の各行の先頭に追加』ボタンを押すたびに、全行頭に指定の文字列(デフォルトでは「★」)が挿入されます。

HTMLソースとJavaScriptソースは以下の通りです。

■HTMLソース:

◆ユーザの入力欄:<input type="text" size="30" id="sampleUserInput" value="です!" />
<input type="button" value="上記の入力内容を、以下の先頭に追加" onclick="AddStringToEachLine();" />
◆文字列リスト:<textarea cols="30" rows="6" id="sampleTargetLines">北海道
東京都
大阪府
</textarea>

最初にinput要素で入力欄を作り、次にinput要素でボタンを作り、最後にtextarea要素で結果表示欄を作っています。textarea要素にはダミーの文字列を3行ほど記述しています。なお、入力欄の装飾に関する記述は省略しています。
スクリプトから利用するため、ユーザが入力するためのinput要素には「sampleUserInput」というid名を、表示結果のtextarea要素には「sampleTargetLines」というid名を、それぞれ加えています。
ボタンがクリックされると、この後で作成する関数「AddStringToEachLine」が実行されます。

■JavaScriptソース:

function AddStringToEachLine() {
   // ユーザの入力を得る
   var UserString = document.getElementById('sampleUserInput').value;
   // 対象文字列を得る
   var TargetString = document.getElementById('sampleTargetLines').value;
   // 先頭に改行を付加し、末尾に改行があれば(=最後に空行があれば)取り除く
   TargetString = "\n" + TargetString.replace(/\n$/,"");
   // 改行部分を対象にして処理
   TargetString = TargetString.replace(/\n/g,("\n" + UserString));
   // 先頭に付加した余分な改行を取り除く
   TargetString = TargetString.replace(/^\n/,"");
   // 書き戻す
   document.getElementById('sampleTargetLines').value = StringToSafety( TargetString );
}

上記のソースでは、以下のような処理をしています。

  1. id名「sampleUserInput」の要素のvalueプロパティの値を、変数「UserString」に格納。
  2. id名「sampleTargetLines」の要素のvalueプロパティの値を、変数「TargetString」に格納。
  3. 変数「TargetString」内の文字列に対して、以下の処理を実行。
    • 先頭に改行「\n」を付加。(=改行を対象にして一括置換することで行頭に文字列を加えるため、先頭にも改行が必要だから。)
    • 末尾の改行を取り除く。(=最後に改行があると、最後の行の後にも余計な文字列を加えてしまうため。ここでは正規表現「\n$」を使って「最後の改行」だけを取り除いています。)
  4. 変数「TargetString」に含まれる改行「\n」を、『改行「\n」に変数「UserString」の内容を加えた文字列』に置き換え。(これで、各行の先頭に文字列が追加されます。)
    上記ソース内の「replace(/\n/g,("\n" + UserString))」の部分が、正規表現を使って文字列を置換している部分です。ここでは、
    • 文字列中に含まれるすべての改行(=「/\n/g」)を、
    • 『ユーザが指定した文字列+改行』の文字列(=「("\n" + UserString)」)に
    書き換えています。 単に「UserString」に置き換えただけだと、改行がなくなってしまうので注意して下さい。「"\n" + UserString」のように記述して、「改行」→「改行+指定文字」のように置き換える必要があります。
  5. 変数「TargetString」から、先ほど(3で)先頭に付加した余計な改行を取り除く。(ここでは正規表現「^\n」を使って「最初の改行」だけを取り除いています。)
  6. 変数「TargetString」の内容を、id名「sampleTargetLines」の要素のvalueプロパティへ書き戻す。

というわけで、複数行の文字列を対象にして、すべての行頭に任意の文字列を加える方法でした。

なお、行頭ではなく行末に文字列を加える方法は、別途「すべての行末に任意の文字列を追加する」で解説しています。

JavaScript TIPS 主要なカテゴリ

現在、以下のカテゴリに区分してTIPSを公開しています。

  • イベント : JavaScriptを実行するトリガーとなるイベントに関するTIPS
  • 入力フォーム : JavaScriptで入力フォームを扱う方法に関するTIPS
  • 情報取得 : JavaScriptで様々な情報を得る方法に関するTIPS
  • 操作・移動 : JavaScriptでブラウザを操作したり表示ページを移動したりする方法に関するTIPS
  • 日付・時刻 : JavaScriptで日付や時刻を扱う方法に関するTIPS
  • 機能 : JavaScriptで何らかの機能を実現する方法に関するTIPS
  • 装飾・内容変更 : JavaScriptで装飾や内容を変更する方法に関するTIPS
  • 計算・変換 : JavaScriptで様々な計算や変換処理を行う方法に関するTIPS

▲各カテゴリ毎に、TIPSのタイトルと概要を一覧できます。ぜひ、いろいろ覗いてみて下さい!

関連書籍・関連ソフトなど