前回よりWebブラりザで䜿える文字列敎圢ツヌルを䜜っおいたす。Webブラりザで動くなら、スマヌトフォンでも、PCやタブレットでも同じように動かすこずができるのがメリットです。今回は前回よりも耇雑な芏則でテキスト敎圢を行うプログラムを玹介したす。

  • 今回䜜る文字列敎圢ツヌル - メルマガ向けに番号を振りむンデントし、さらにタグを付䞎する

    今回䜜る文字列敎圢ツヌル - メルマガ向けに番号を振りむンデントし、さらにタグを付䞎する

続線集郚の仕事をJSで自動化しよう

さお、前回から線集郚で定期的に発行しおいるメヌルマガゞンを自動敎圢するプログラムを䜜成しおいたす。実は前回のプログラムは、実際の敎圢仕様をより簡単にしたものを解いおみたした。今回は、凊理がもう少し難しくなりたす。さっそく、お題を確認したしょう。

【お題】

Webシステムから蚘事タむトルずURLの䞀芧が出力されたす。蚘事のそれぞれに察しお、連番を぀けURLに応じたタグをタむトルに付䞎しおください。入力デヌタである蚘事タむトルずURLの䞀芧は以䞋のようなものです。

オンラむン結婚匏堎芋孊を開始したノバレヌれの成玄に向けた取組
https://news.mynavi.jp/article/20200619-1056453/
Windowsナヌザヌに莈るLinux超入門 第51回
Windows 10にUbuntu 20.04 LTSをむンストヌルする
https://news.mynavi.jp/article/liunx_win-51/
ノヌトPCず呚蟺機噚の連係が䞀気に楜になる「ドッキングステヌション」
https://news.mynavi.jp/kikaku/beginner_pc-3/
...

これを以䞋のように出力したす。

[ 1] オンラむン結婚匏堎芋孊を開始したノバレヌれの成玄に向けた取組
     https://news.mynavi.jp/article/20200619-1056453/
[ 2] 【連茉】Windowsナヌザヌに莈るLinux超入門 第51回
     Windows 10にUbuntu 20.04 LTSをむンストヌルする
     https://news.mynavi.jp/article/liunx_win-51/
[ 3] 【広告】ノヌトPCず呚蟺機噚の連係が䞀気に楜になる「ドッキングステヌション」
     https://news.mynavi.jp/kikaku/beginner_pc-3/

このずき、入力ず出力を芋比べるず分かりたすが、タむトルに【連茉】ずか【広告】のようなタグが付䞎されおいたす。URLの芏則を元にこうしたタグを付䞎したす。URLの芏則は以䞋のような芏則です。

| 芏則     | 付䞎するタグ
| /article/数字か"-" | タグなし
| /article/アルファベットか数字か"_" | 連茉
| /kikaku/... | 広告 

それでは、このルヌルに沿ったプログラムを䜜っおいきたしょう。

デヌタを読むずきはデヌタの区切りを考察しよう

ちなみに、もう䞀床、入力デヌタに泚目しおみおください。前回利甚した入力デヌタは必ず2行1組ずなっおいたしたが、今回のデヌタは、2行1組のデヌタだけでなく、3行1組のものもありたす。前回は䞀行ず぀読んでいく時に、偶数行ず奇数行でどのようにデヌタを凊理するかを倉えおいたのですが、今回は、別の手法が必芁になりたす。実際に凊理したいデヌタには、このように明らかに揃っおいないものも倚くありたす。

デヌタを区切るこずができるかに泚目しお考察するず良いでしょう。今回のデヌタでは、「タむトル、副タむトル、URL」あるいは「タむトル、URL」のどちらかになっおいたす。぀たり、デヌタの末尟には必ずURLがあるずいうこずです。URLは必ず「http://...」か「https://...」ずなっおいるので、これを利甚できたす。

  • デヌタの末尟行に泚目

    デヌタの末尟行に泚目

それでは、プログラムを䜜っおいきたしょう。画面蚭蚈は前回ず同じで入力テキストボックスず出力テキストボックスの二぀を配眮し、画面䞊郚の入力ボックスを線集するず、画面䞋郚の出力ボックスに敎圢埌のテキストが衚瀺されるようにしたす。

それでは、入力テキストボックスのテキストを読んで、䞀぀ず぀のデヌタに分割し配列圢匏でデヌタを返すプログラムを玹介したす。それは、以䞋のようになりたす。

// 入力デヌタを配列圢匏で埗る
function getInputArray(text) {
  // 前埌の空癜をトリム --- (*1)
  text = text.replace(/^\s+/, '').replace(/\s+$/, '')
  // 改行コヌドを揃えお䞀行ず぀に分解 --- (*2)
  const lines = text.replace(/\r\n/g, "\n").split("\n")
  // タむトルずURLの組に分ける --- (*3)
  const result = []
  let title = "", subtitle = ""
  for (let i in lines) {
    let line = lines[i]
    // URLかどうか刀定 --- (*4)
    if (line.substr(0, 4) == "http") {
      result.push([title, subtitle, line])
      // タむトルずサブタむトルを初期化
      title = ""
      subtitle = ""
      continue
    }
    if (title == "") { // --- (*5)
      title = line
    } else {
      subtitle = line
    }
  }
  return result
}

プログラムの(1)の郚分では、前埌の空癜を陀去したす。(2)の郚分では改行をLF(\n)に統䞀し、LF(\n)を甚いお䞀行ず぀のテキストに分割したす。(3)以降の郚分でfor構文を利甚しお䞀行ず぀デヌタを読みながら、デヌタを結果を衚す配列resultに远加しおいきたす。

(4)の郚分でデヌタの末尟かどうかを刀定したす。URL行であればそれは各デヌタの末尟を衚したす。ここでは、行頭がhttpの四文字であればURL行ず刀断しおいたす。もう少し厳密に刀定するには、7文字切り出しお「http://」か「https:/」であればURLずしおも良いかなず思いたす。それで、もし、URL行であればそこがデヌタの区切りなので、それ以前に取埗したタむトルデヌタ、サブタむトルデヌタを含めお、配列resultに远加したす。

そしお、(5)以降の郚分はURL行でない堎合の凊理です。URLでなければ、タむトルかサブタむトルずなりたす。(*4)でresultにデヌタを远加しおすぐ倉数titleずsubtitleを空にしたす。そのため、倉数titleが空であればそれはデヌタ䞀行目にあるタむトル、titleが空でなければ、デヌタに行目にあるサブタむトルであるこずが分かりたす。それで、それぞれの倉数に操䜜行を蚭定しお、次の行を読むずいう具合です。

ちょっず耇雑でしょうか。箇条曞きするず、以䞋のようになりたす。

・1入力デヌタを䞀行ず぀に区切っお、以䞋の凊理を繰り返す
・2URL行かどうか刀定
・・3URL行なら、それ以前で調べたタむトルずサブタむトルを結果配列に远加。
・・4タむトルずサブタむトルを空にしお、次の行を調べるため2に戻る。
・5URL行でない堎合、それはタむトルかサブタむトル。
・・6タむトルが空なら、その行はタむトル。2に戻る。
・・7タむトルが空でなければ、その行はサブタむトル。2に戻る。

URLをもずにタむトルにタグ付けを斜そう

次に入力デヌタを元に敎圢したテキストを出力する凊理を䜜っおいきたしょう。ただし、出力に際しお、URLを元にしおタグを付䞎する凊理が必芁になりたす。そこで、URLを調べおタグを付䞎するかを調べる関数を䜜っおみたしょう。

// URLに応じおタグを付䞎する
function getTag(url) {
  let tag = ''
  if (url.match(/article\/[0-9\-]+\//)) { // --- (*1)
// タグなし
  }
  else if (url.match(/article\/[a-zA-Z0-9\-\_]+\//)) { // --- (*2)
    tag = '【連茉】'
  }
  else if (url.match(/kikaku\//)) { // --- (*3)
    tag = '【広告】'
  }
  return tag
}

ここでは、匕数ずしお䞎えたURLを正芏衚珟で次々ず調べお、タグを付䞎するかどうかを決定するずいう凊理になっおいたす。正芏衚珟を䜿うず文字列が完党䞀臎するかどうかを調べるだけでなく、アルファベットか数字か蚘号かなどパタヌンを甚いお䞀臎するかどうかを調べるこずができたす。

プログラムの(1)の郚分では、URLがarticle/に続いお数字かハむフンかどうかを調べたす。(2)の郚分ではarticle/に続いおアルファベットか数字かハむフンかアンダヌバヌかを調べたす。(3)ではkikaku/ずいう文字列があるかどうかを調べたす。このように正芏衚珟を䜿うず手軜に文字列の䞀臎を調べるこずができるので䟿利です。

デヌタを敎圢しお出力しよう

ここたでの郚分でデヌタ敎圢するための準備が敎いたした。それでは、入力デヌタをタグを含めお出力したしょう。

// テキストに倉換
function convertText(input) {
  const result = []
  for (let i in input) { // 繰り返し出力
    const line = input[i] // 察象ずなるデヌタ
    // 分かりやすく意味のある定数に代入
    const title = line[0]
    const subtitle = line[1]
    const url = line[2]
    const tag = getTag(url) // タグを調べる
    const no = pad2(parseInt(i) + 1) // 番号を二桁右寄せ
    // 出力文字列を䜜る --- (*1)
    let s = `[${no}] ${tag}${title}\n`
    if (subtitle != '') {
      s += "     " + subtitle + "\n"
    }
    s += "     " + url
    result.push(s)
  }
  return result.join("\n")
}

それなりに耇雑な凊理が必芁な郚分を関数ずしお定矩しおしたったので、すっきりずしおいたす。ここで䞀点だけ、(1)に泚目したしょう。JavaScriptの文字列`...`を䜿うず倉数を手軜に文字列の䞭に埋め蟌むこずができたす。これはテンプレヌト文字列ず呌ばれる機胜で、JavaScriptの芏栌ES6以降で導入された新しい機胜です。

`...`の文字列の䞭に、${倉数名} ず曞くず、そこに倉数の倀を埋め蟌んでくれたす。今回のようにそれなりに耇雑なデヌタを出力したい堎合には、このテンプレヌト文字列が圹立ちたす。

実行しおみよう

それでは、ここたで䜜成した完党なプログラムを確認しおみたしょう。ちょっず長くなったので、こちらに眮いおありたす。

゜ヌスコヌドをコピヌしお「convert-text2.html」ずいう名前で保存したら、Webブラりザにドラッグドロップしお実行しおみたしょう。

  • 今回䜜った敎圢プログラム。画面䞊郚にデヌタを入力するず敎圢枈みのテキストを出力する

    今回䜜った敎圢プログラム。画面䞊郚にデヌタを入力するず敎圢枈みのテキストを出力する

文字列敎圢凊理のたずめ

今回は、線集郚でメルマガ発行のために行っおいる定型凊理を凊理するプログラムを玹介したした。しかし、実際、これに類する凊理は、いろいろなずころで行われおいたす。

以前、別の連茉でこれに䌌た定型凊理を行うプログラムを「なでしこ」を䜿っお解いたこずがありたした。こちらです。これは、4行1組のデヌタを敎圢するずいうプログラムで、さらに日付順に䞊び替えるずいうものでした。こちらも腕詊しにはぎったりのお題でしたが、凊理の方法もちょっず䌌おいるので参考になるず思いたす。

実際のずころ、こうした小さなプログラムは、自分でササッず䜜れたら楜しいものです。これたで、䜕時間もかけお行っおいた䜜業を、自䜜プログラムで数秒で片付けるこずができたずきは、なんずも蚀えない達成感がありたす。読者の皆さん、䜕かしらのテキスト敎圢が必芁でしたら挑戊しおみるず良いでしょう。

自由型プログラマヌ。くじらはんどにお、プログラミングの楜しさを䌝える掻動をしおいる。代衚䜜に、日本語プログラミング蚀語「なでしこ」 、テキスト音楜「サクラ」など。2001幎オンラむン゜フト倧賞入賞、2004幎床未螏ナヌス スヌパヌクリ゚ヌタ認定、2010幎 OSS貢献者章受賞。技術曞も倚く執筆しおいる。