🐼変異種:晴読雨読:東京都の区市町村別累計確認感染者数をPDFからコピペしてスプシに貼り付ける過程を半自動化:ジャバスクリプトでファイル読み込み ― 2021年06月04日 10:47
変異種:晴読雨読:東京都の区市町村別累計確認感染者数をPDFからコピペしてスプシに貼り付ける過程を半自動化:ジャバスクリプトでファイル読み込み
先週土曜日昼の会食の際、愚弟にアドバイスを求めたんだが、そんなもんはプロが手を出すもんじゃないから、ネットで調べてサンプルコードをコピペしろと、何とも連れない返事。
まあいい。
翌日から伊豆大島にゆるゆるのダイビングをしに行ったので、水曜日までは構想のみ。
昨日は、天気も良く、今月1日からから大井町のフィットネスも再開されているので行こうかどうしようか迷ったが、筋肉痛にかこつけてサボリ決定。
ついでに、久しぶりにプログラムを書こうと決めた。
ウインドウズの環境で、なるべくそのまま使いたいから、バッチファイルで作れると楽ちんでいいので調べたんだが、良く分らなかった(たぶん、バッチファイルが正解のような気がするんだがな)。
以前、ベーシックで減圧ソフトを書いたりして、変数の回しとかは経験済みなので、その線で当たったんだが、外部ファイルからデータ取り込んだりするのは参考になるものが少なく、環境も作らなくてはならないので、今回は見送り。
結構時間を掛けて調べたのは、Jスクリプトというマイクロソフト御用達のスクリプト言語。
ジャバスクリプトに似ているんだが、いろいろ調べても痒いところに手が届かない。
外部ファイルの取り込みとかはふつーにできるし、テキストの置き換えにも対応していて、今回はこれで行こうかと粘ったんだが、置き換えの細かいところが分からず涙を呑んで断念(たぶん、これも正解かも知れない)。
結論としては、減圧ソフトとかでも使ったジャバスクリプトが、ネット上の情報も多く、必要なサンプルコードをスパゲッティな感じで繋げていけばナポリタン(目的とするプログラム)が作れそうな感じで書き始める(実際には、コピペですが)。
まずは、元になる東京都福祉保健局のPDFからコピペしたテキストから。
(別紙
◆令和3年6月3日16時45分時点)
https://www.fukushihoken.metro.tokyo.lg.jp/hodo/saishin/corona2103.files/2103_.pdf
「【参考】区市町村別患者数(都内発生分) (6月2日時点の累計値)」という前日のデータを区市町村別に集計した表があるので、マウスでコピペしてウインドウズのメモ帳に貼り付ける。
「851 (812) 2612 (2513) 5301 (5134) 8783 (8624) 2401 (2297) 2969 (2847) 3224 (3100) 5307 (5095) 4710 (4525) 4404 (4239) 7854 (7604)
11712 (11186) 4666 (4488) 5221 (5052) 6430 (6198) 4260 (4084) 3648 (3481) 2604 (2460) 6064 (5764) 7148 (6894) 7425 (7220) 5496 (5311)
6861 (6610) 3943 (3820) 1326 (1241) 1278 (1224) 1512 (1443) 791 (779) 1844 (1730) 789 (763) 1899 (1812) 2622 (2520) 930 (884)
1113 (1064) 1148 (1120) 815 (761) 807 (747) 426 (398) 475 (448) 592 (550) 454 (430) 390 (370) 651 (625) 367 (354)
889 (870) 537 (521) 343 (334) 545 (494) 1541 (1491) 179 (172) 105 (94) 10 (10) 25 (25) 23 (23) 0 (0)
1 (1) 1 (1) 4 (4) 2 (2) 9 (7) 0 (0) 4 (4) 13496 (13359) 76」
①カッコ内は累計回復者数ということだが、浮沈子は使っていないので、これを手で消していた(かなり面倒くさい)。
②また、改行が4か所ほどあるので、これも消す(手間ではないけど、簡単に出来そうだったので:意外と難航した)。
③最後に、グーグルスプレッドシートに貼り付ける際に、縦書きで(データが縦に並ぶように)行うために整形する。
いろいろネットの記事を読んだんだが、主に参考にしたのは「侍エンジニアブログ」というページ。
やや、宣伝がうるさいけど(プログラミング教室の勧誘)、必要な所だけつまみ食いして撤退したい浮沈子には無縁だ(体系的にプログラミングの勉強をしたことはありません)。
まず、食いついたのは、メインのメソッドであるデータの置き換えをする機能のページ。
(【JavaScript入門】replaceの文字列置換・正規表現の使い方まとめ!)
https://www.sejuku.net/blog/21107
参考にしたコード。
「文字列に含まれているカンマを除去する方法:
var str = '1,234,567';
var result = str.replace(/,/g, '');
console.log( result );」
もう一つ、実際にコピペに使ったもの。
(JavaScriptのreplaceメソッドを使って様々な置換を試してみよう)
https://techplay.jp/column/535
「全角空白・半角空白を削除する:
var sample='吾 輩 は 猫 で ある ';
sample=sample.replace(/\s+/g,'')
console.log (sample)」(\はバックスラッシュ:以下同じ)
浮沈子の開発環境は、エディターはウインドウズのオマケのメモ帳、実行環境はグーグルクロームなので、コンソールとかは使わない(使えばいいのに・・・)。
で、結果を吐き出す先はブラウザーにする。
「document.write(sample) ;」
文字列を効率よく扱うには、正規表現を使うのがいいらしいということで、その辺りのお勉強も。
(【JavaScript入門】4つのパターンで理解する正規表現の使い方まとめ!)
https://www.sejuku.net/blog/20973
参考にした部分。
「「\d」0〜9の数字」
「今回のように数字であれば、「\d」を1つ記述してその後に続けて「*」「+」を書くだけでどんな桁数の数字にもマッチすることになります!」(今回は「*」を使用:カッコ内(累計回復者数)には空文字はないので)
「「time」はそのまま固定で、末尾の「s」に続けて「?」を付けることで、「s」の「ある」「なし」を表すことが出来るのです!」(改行コードのところで「?」が出てきます。)
「正規表現で扱う「特殊文字(. * + ^ | [ ] ( ) ? $ { }など)」は、パターンを作成する時にエスケープしなければいけないケースがあります。」
「正規表現でエスケープ処理を行うのに必要なのは「 (バックスラッシュ)」です」
累計回復者数はカッコ「( )」で囲まれているので、これを正規表現で扱うには、エスケープ処理が必要だからな。
コードを書く(コピペする)上で、MSゴシックだとバックスラッシュが正しく表記されないので、エディターであるウインドウズのメモ帳のフォントを「Arial」に変更しておく。
いろいろ試したんだが、カッコつきの数字(回復者数)を、いきなりブラウザーの改行記号である<br>に置き換えようとすると2回改行されてしまった。
そこで、仮に「p」(文字はテキトーです)で置き換えておいて、「p」をさらに<br>に置き換えることにした(もっとうまいやり方があると思いますけど)。
元データに改行が4か所ほど混ざっているので、これを取り除こうと苦労した。
作成途中では、データをベタ文字列で変数に貼り付けていたので、これを弄ってもうまく置き換えてくれない。
後述の外部ファイルからの読み込みを行って、その内部データに対して置き換えを行ったところ、見事に消えてくれた!。
(【JavaScript入門】文字列を改行する方法(改行コード/「\n」/置換))
https://www.sejuku.net/blog/55631
「改行コードはOSごとに異なります。:
Unix:\r
mac(OS X):\n
mac(OS 9以前):\r
Windows:\r\n」
これらを正規表現で一元的に表記すると、「\r?\n」となるわけだな(ロジカルには「\r?\n?」になるような気も)。
最後は、まあ、順序的には逆なんだが、ローカルのファイルからデータを読み込むところ。
これは、さっぱり分からないので、変数とかもそのままコピペして、置き換え処理のところで入れ替えたりした(禁じ手!)。
(JavaScriptでファイル処理! JSONやCSVなどのファイルを読み込もう)
https://www.sejuku.net/blog/32532
「ファイルの読み込みを実現させるためには、一般的にFile APIを使います。」
「これは、HTML5から利用できるようになった機能(API)になります。JavaScriptからFile APIで提供されているメソッドを組み込むことで簡単にPCのローカルファイルを読み込ませることが可能です。」
簡単とか書いてあるけど、浮沈子には何をやっているのかさっぱりだ。
ここは、そのままコピペして、ファイルの中身を指している変数は、途中で入れ替えるという禁じ手を使ってしまう(スパゲッティープログラミングで、最もやっちまう方法かあ?:良い子はマネしないでね!)。
まあ、そのままでもよかったんですが・・・。
参考にしたコード(つーか、そのままコピペ)。
「<body>
<form name="myform">
<input name="myfile" type="file" />
</form>
<script>
//Form要素を取得する
var form = document.forms.myform;
//ファイルが読み込まれた時の処理
form.myfile.addEventListener('change', function(e) {
//ここにファイル取得処理を書く
})
</script>
</body>」
取得処理のところも、次のコードをそのままコピペした。
「var form = document.forms.myform;
form.myfile.addEventListener( 'change', function(e) {
var result = e.target.files[0];
//FileReaderのインスタンスを作成する
var reader = new FileReader();
//読み込んだファイルの中身を取得する
reader.readAsText( result );
//ファイルの中身を取得後に処理を行う
reader.addEventListener( 'load', function() {
//ファイルの中身をtextarea内に表示する
form.output.textContent = reader.result;
})
})」
説明の意味は、さっぱり分からないが、ちゃんとプログラミングのお勉強している人には簡単なんだろう。
で、試行錯誤を重ねて、出来上がったスパゲッティーナポリタンがこれ・・・。
「<html>
<body>
<form name="myform">
<input name="myfile" type="file" />
</form>
<script>
var form = document.forms.myform;
form.myfile.addEventListener( 'change', function(e) {
var result = e.target.files[0];
//FileReaderのインスタンスを作成する
var reader = new FileReader();
//読み込んだファイルの中身を取得する
reader.readAsText( result );
//ファイルの中身を取得後に処理を行う
reader.addEventListener( 'load', function() {
//②改行除去(ここで、変数の入れ替え!:reader.result→sample)
sample=reader.result.replace(/\r?\n/g,'');
//①カッコ内を仮置き換えpへ(カッコ内を消す処理(その1))
sample=sample.replace(/\(\d*\)/g,'p');
//③仮置き換えpをブラウザー上の改行<br>へ(カッコ内を消す処理(その2)+横書きを縦書きへ)
sample=sample.replace(/p/g,'<br>');
//ファイルの中身をブラウザー上に表示する
document.write(sample) ;
})
})
</script>
</body>
</html>」
①、②、③は、概ね今回の処理でやりたかったことと対応している。
ファイルの選択をもっとシンプルにしたいとか(一応このままでも、クロームでは、ドラッグアンドドロップでも出来ます)、スパゲッティコードを何とかしたいとか、ファイルの読み込みをちゃんと理解したいとか、出力先をブラウザー上ではなく、ファイルにしたいなど課題は山積だが、当初のイメージ通りの仕掛けになったのでいいことにする。
今回の収穫は、これまでちゃんと勉強したことがなかった正規表現について、上っ面だけでも一通り眺めたことだろうな。
開発環境と実装にジャバスクリプトを選んだのは、正解かどうか分からない。
気力と時間が許せば、Jスクリプトは手を付けてみたい気もするし、何より、バッチファイルでさっくり処理したい。
同じことを、異なるプログラミング言語で表現できれば、何となく豊かになった気がするのは、自然言語と同じだ。
メモ帳にコードを書いて、ファイル名にhtml拡張子をつけ、ダブルクリックで起動すると、ブラウザーに画像のタブが出るので、インプットメソッドでPDFから貼り付けたテキストファイルを選ぶだけで、ブラウザーに縦書きの数字が上書きで並び、それをそのままスプシにコピペする。
従来は、PDFから貼り付けたメモ帳で手処理で改行を取り除いたり、区切り文字として入っている半角スペースを入れたり、それらを含めて、半角スペースをタブに置き換えたりという前処理から始まり、作業用のスプシを開き、横書きのまま貼り付けてからコピーし、特殊貼り付け→転置して貼り付けで縦横変換し、1行おきに拾うために0、1で交互にフラグを立てたり並べ替えを行って、ようやく縦書きの累計感染者数だけのデータを得ていた。
改行除去などの前処理もなし、1つおきに拾うこともなし、縦横変換もなし。
PDFからテキストファイルにコピペして、そのまま保存。
デスクトップからジャバスクリプト入りのファイルを起動してタブを開かせ、保存したファイルを選択すれば、整形済みのデータがブラウザー上に展開される。
そのデータ(最初に引用したものと同じ6月2日分)
「851
2612
5301
8783
2401
2969
3224
5307
4710
4404
7854
11712
4666
5221
6430
4260
3648
2604
6064
7148
7425
5496
6861
3943
1326
1278
1512
791
1844
789
1899
2622
930
1113
1148
815
807
426
475
592
454
390
651
367
889
537
343
545
1541
179
105
10
25
23
0
1
1
4
2
9
0
4
13496
76」
それを、集計してグラフ化しているスプシにコピペしてお終い。
時間的には、大した話じゃないけど、毎回毎回、同じ処理を繰り返し行う苦痛が無くなるだけでもマシというものだ。
このブログ記事は備忘のために書いている。
参考に開いたホームページとかは、グーグルに筒抜けだしな。
どーせ筒抜けなんだから、試行錯誤した手順とかも、得意のAIでブログ記事に仕立てて書いて欲しいもんだな。
そうすれば、半徹(半分徹夜)しなくても済んだかもしれないのにな。
今朝は雨。
東京はそれ程でもないけど、西日本は大雨だそうだ。
さて、飯でも食いに行って、爆睡するか・・・。
<以下追加>ーーーーーーーーーー
(JavaScriptのイベントの仕組みが一発で理解できるウェブアプリ「Explore DOM Events」レビュー)
https://gigazine.net/news/20210603-explore-dom-events-javascript/
「JavaScriptには、特定の動作が発生した際にそれに応じてコードを実行する「イベント」という仕組みが存在しています。」
ファイルを読み込んで処理系に渡すときに、どうもイベントドリブンな仕掛けを使っている気がしたので、たまたま読んだギガジンの記事をリンクしておく。
それよりも、この記事からリンクされているチュートリアルは、まあ、英語の直訳だが日本語化されていて、ジャバスクリプトのお勉強には向いている気がする(「イベント」、「DOM」からリンクしている)。
気が向いたら、取り組んでみるのもいいかもしれないな・・・。
<さらに追加>ーーーーーーーーーー
6月5日記。
今日も、フィットネスをサボって、シコシコとプログラミングに勤しむ・・・。
(JavaScript テキストエリアの値を取得/設定する)
https://itsakura.com/js-textarea
考えてみれば、わざわざテキストファイルを経由しなくても、ジャバスクリプトを使うわけだからブラウザー上のテキストエリアに直接コピペした方が簡単に決まっている。
PDFファイルからコピーしたデータは、テキストエリアにペーストすれば、当然テキストデータとして扱われるだろうから(まんまや!)、それをそのままハンドリングすればいい・・・。
で、上記のページを参考に(えーと、例によってコピペしただけですが)茹で上げたスパゲッティーミートソース(ナポリタン改め)が、これ。
「<html>
<body>
<textarea id="textarea3" value="1" cols="140" rows="10" maxlength="1000"></textarea><br>
<input type="button" value="変換" onclick="clickBtn5()" />
<input type="button" value="クリア" onclick="clickBtn7()" />
<script>
function clickBtn5() {
let ta3 = document.getElementById("textarea3").value;
//改行除去
ta3=ta3.replace(/\r?\n/g,'');
//カッコ内を仮変換pへ
ta3=ta3.replace(/\(\d*\)/g,'p');
//仮変換pをブラウザー上の改行へ
ta3=ta3.replace(/p/g,'<br>');
//ファイルの中身をブラウザー上に表示する
document.write(ta3) ;
}
function clickBtn7() {
document.getElementById("textarea3").value = "";
}
</script>
</body>
<html>」(\はバックスラッシュ)
出力は、テキストエリア内でも試してみたんだが(その方がカッコいいし)、半角スペースが残ってしまって上手くいかなかったので、今回はそこは弄らずに、ウェブページ上に変換後のデータを上書きでぶちまける(作業的には、これをスプシのセルにコピペすることになる)。
参考にしたページ上では、クリアボタンが実装されているけれど、サンプルコードでは省略されている。
何とかならんもんか・・・。
「テキストエリアに値を設定する:
・・・
テキストエリアをクリアする場合は、空文字("")をセットします。」
クリアボタンは、これを参考にボタンとファンクションを追加した(ボタンのidとか付けてなかったりして、もう、テキトーです)。
今回は、変数は途中で変えたりしないで同じものを使う。
サンプルプログラムのconstのままだと、書き換え時の再代入を受け付けないので、letにしてみたら動いた(スコープであるfunction clickBtn5()内では再代入も可:もちろん、varでも動きました)。
変数の定義にvar、let、constのどれを使うかについては懇切丁寧な解説のページがあった。
(JavaScriptのletとは?知っておくべき特徴と使い方について)
https://www.sejuku.net/blog/58429
「・varは使わずに、これからはletかconstを利用する
・letは再宣言不可でブロックスコープという特徴がある
・constは再代入も不可だがオブジェクトなどの値は変更可能」
この辺りは、例によってテキトーなので、美しくなくてもいい。
動くプログラムが絶対の正義だからな・・・。
<さらにさらに追加>ーーーーーーーーーー
(今すぐ対策できる!HTMLで文字化けを直す方法【初心者向け】)
https://techacademy.jp/magazine/9929
弄っているうちに、ボタンの表示(「変換」「クリア」)が文字化けしたので対策する。
「HTMLファイルは文字コードUTF-8で保存する。」
「HTMLのmetaタグに charset=”UTF-8″ を指定する。」
「<head>
<title>sample</title>
<meta http-equiv="content-type" charset="UTF-8">
</head>」
こんなことになったのは、またまた改良(?)して、テキストエリアに吐き出すことにしたからか。
ーーーーー<<現在のソースコード:ここから>>ーーーーー
「<html>
<head>
<title>PDF2TXT</title>
<meta http-equiv="content-type" charset="UTF-8">
</head>
<body>
<textarea id="textarea3" value="1" cols="140" rows="10" maxlength="1000"></textarea><br>
<input type="button" value="変換" onclick="clickBtn5()" />
<input type="button" value="クリア" onclick="clickBtn7()" />
<script>
function clickBtn5() {
let ta3 = document.getElementById("textarea3").value;
//元データの改行除去
ta3=ta3.replace(/\r?\n/g,'');
//カッコ内を改行へ
ta3=ta3.replace(/\(\d*\)/g,'\r\n');
//ファイルの中身をテキストエリアに表示する
document.getElementById("textarea3").value = ta3;
}
//テキストエリアのクリア処理
function clickBtn7() {
document.getElementById("textarea3").value = "";
}
</script>
</body>
<html>」
ーーーーー<<現在のソースコード:ここまで>>ーーーーー
今まで仮変換していた「p」とかいう仮文字をやめて、ダイレクトに改行コードを入れた(さすがに、テキストエリアに入れると<br>は、そのまま表示されるからな)。
ウインドウズ環境だから、「\r\n」としたんだが、どうもこれが原因らしい(未確認)。
で、上記のようにヘッドでキャルセットを指定したら、化けなくなった。
随分完成形に近づいている。
ブラウザー経由の処理だが、サーバー上に置いておけば、ネット環境からも使える(ニッチな用途だけど)?
まあ、こんだけだから、メモ帳にコピペして拡張子をhtmlとかにしてからダブルクリックで実行してもいいか・・・。
カッコ内のデータを直接改行コードに変換した際に、半角スペースが付いている感じだったけど(trim()とか使っても、取れませんでした。)、スプシにコピペしてみたら、ちゃんと数値として読み込めたので、このスタイルで行くことにした。
結果が全て。
無事に昨日(6月4日分)のデータもスプシに放り込んで、今日の作業はお終い。
JスクリプトやVBスクリプト、ウインドウズバッチファイルなどでも、同じ様な処理が出来そうだ。
ツールとしては、文字置換は一般的な処理で、テキストファイルに落とし込んでおけば、リプレイスなどと同じようなコマンド(メソッド?)で変換してくれる。
対象とするファイル、置き換え前文字列、置き換え後文字列を指定して、任意の返還をしてくれる汎用ツールのようなものもあった。
(JScript でテキストファイルの文字列を置換する)
https://norastep.hatenablog.com/entry/2015/12/05/205308
「今回は、JScript を用いてテキストファイルの文字列を置換するスクリプトを作りました。」
(windows dosで正規表現の置換が実行可能なツールをつくりました)
http://defmementomori.hateblo.jp/entry/2017/03/17/210144
「正規表現の置換を実行するバッチを組みたい」
「そこでvbsでツールを作りました。」
(バッチファイルでテキストファイル内の文字列置換)
https://knowledge.reontosanta.com/archives/816
「Windowsのバッチファイルでテキストファイル内の特定の文字列を置換する方法」
もちろん、各種開発環境を導入すれば、何でもできるだろう。
ウインドウズの素の環境で、ブラウザー以外の実行環境がない状態では、候補はこれくらいか(パワーシェルとかだと、一発だそうですが)。
今回は、やりたいこと(ニーズ)に特化して、出来ること(シーズ)を選んだ。
Cで書け!とか、パールが最適!とか、パイソンでしょう!とか、浮沈子には皆、敷居が高い。
コードを書いた経験は、DOSのバッチファイル、ベーシック、ジャバスクリプト程度だ。
言語の仕様はどんどん変わっていくから、キャッチアップしないとな。
以前は、ジャバスクリプトで外部ファイルを扱うことはできなかった(浮沈子が知らなかっただけかも)。
HTML5.0から、限られた範囲でのアクセスが可能になり、汎用的な処理にも使えるようになった。
最終的には、PDFからのコピペをテキストエリアに読み込む方法にしたけれど、ファイルの中のデータを弄るという、ドキドキする体験も出来たからな(イベントドリブンな処理の理解は、次回持越しだな)。
ジャバスクリプトは、コンピューターのフロントエンドの処理に大活躍しているようだ。
動的なブラウザーのぺージを作るには欠かせないし、クライアントサイドでのローカル処理で済ませられることを済ませてしまえば、通信コストの削減にも繋がる。
サーバーサイドで動くスクリプトもあるようだ(未確認)。
プログラムと言えば、紙のコード表に手書きして、パンチカードに打ち込んでもらい、光学読み取り機で磁気テープに記録し、夜中にバッチ処理を走らせるものだという時代から付き合っている浮沈子にとって、現代は夢のような時代だ。
掌に乗るスパコンを、ありとあらゆる人々が持ち歩き、溢れるような通信環境で高品位動画を再生して楽しんでいる。
テレビ電話(死語です!)は、新型コロナの時代になって当たり前の存在になり、気の利いた会社はリモートワークに移行して実績を上げている。
そんな時代に、テキストデータのカッコ外して取っ払い、改行コードに置き換えたりして、何が面白いのか・・・。
そのデータが、都内感染者の区市町村別内訳だったりするところが、時代を反映しているわけだ(そうなのかあ?)。
まあ、どうでもいいんですが。
動画も、バーチャルリアリティも結構だけど、コンピューターの基本はテキストデータの処理だ(時代錯誤!?)。
数値を演算したり、テキスト文書を操作したり。
浮沈子は、ブログを書き(大部分コピペし)、たまにプログラムを書き(殆ど全てコピペし)、画像(静止画)を撮って(大体キャプチャかコピペして)楽しんでいる。
今回も、コピペして貼り付け、ワンクリックで成果物を得た(それをまた、コピペして貼り付けるんだがな)。
定型処理を手作業で行うという苦痛から逃れて楽をするために、半徹して突破し、さらに2日掛かりで使いやすくした。
その作業の方が余程骨が折れるが、苦痛ではない。
新しいことを学ぶという、得難い経験をさせてもらえた。
学校のお勉強を楽しいとは思わなかったけど、自分がやりたいことを解決するために、調べたり、人様の知恵を借りたり(=コピペ?:カンニングともいう)することは楽しい。
楽をするための苦労は楽しい。
楽あれば苦あり、苦あれば楽あり。
塞翁が馬ということか・・・。
先週土曜日昼の会食の際、愚弟にアドバイスを求めたんだが、そんなもんはプロが手を出すもんじゃないから、ネットで調べてサンプルコードをコピペしろと、何とも連れない返事。
まあいい。
翌日から伊豆大島にゆるゆるのダイビングをしに行ったので、水曜日までは構想のみ。
昨日は、天気も良く、今月1日からから大井町のフィットネスも再開されているので行こうかどうしようか迷ったが、筋肉痛にかこつけてサボリ決定。
ついでに、久しぶりにプログラムを書こうと決めた。
ウインドウズの環境で、なるべくそのまま使いたいから、バッチファイルで作れると楽ちんでいいので調べたんだが、良く分らなかった(たぶん、バッチファイルが正解のような気がするんだがな)。
以前、ベーシックで減圧ソフトを書いたりして、変数の回しとかは経験済みなので、その線で当たったんだが、外部ファイルからデータ取り込んだりするのは参考になるものが少なく、環境も作らなくてはならないので、今回は見送り。
結構時間を掛けて調べたのは、Jスクリプトというマイクロソフト御用達のスクリプト言語。
ジャバスクリプトに似ているんだが、いろいろ調べても痒いところに手が届かない。
外部ファイルの取り込みとかはふつーにできるし、テキストの置き換えにも対応していて、今回はこれで行こうかと粘ったんだが、置き換えの細かいところが分からず涙を呑んで断念(たぶん、これも正解かも知れない)。
結論としては、減圧ソフトとかでも使ったジャバスクリプトが、ネット上の情報も多く、必要なサンプルコードをスパゲッティな感じで繋げていけばナポリタン(目的とするプログラム)が作れそうな感じで書き始める(実際には、コピペですが)。
まずは、元になる東京都福祉保健局のPDFからコピペしたテキストから。
(別紙
◆令和3年6月3日16時45分時点)
https://www.fukushihoken.metro.tokyo.lg.jp/hodo/saishin/corona2103.files/2103_.pdf
「【参考】区市町村別患者数(都内発生分) (6月2日時点の累計値)」という前日のデータを区市町村別に集計した表があるので、マウスでコピペしてウインドウズのメモ帳に貼り付ける。
「851 (812) 2612 (2513) 5301 (5134) 8783 (8624) 2401 (2297) 2969 (2847) 3224 (3100) 5307 (5095) 4710 (4525) 4404 (4239) 7854 (7604)
11712 (11186) 4666 (4488) 5221 (5052) 6430 (6198) 4260 (4084) 3648 (3481) 2604 (2460) 6064 (5764) 7148 (6894) 7425 (7220) 5496 (5311)
6861 (6610) 3943 (3820) 1326 (1241) 1278 (1224) 1512 (1443) 791 (779) 1844 (1730) 789 (763) 1899 (1812) 2622 (2520) 930 (884)
1113 (1064) 1148 (1120) 815 (761) 807 (747) 426 (398) 475 (448) 592 (550) 454 (430) 390 (370) 651 (625) 367 (354)
889 (870) 537 (521) 343 (334) 545 (494) 1541 (1491) 179 (172) 105 (94) 10 (10) 25 (25) 23 (23) 0 (0)
1 (1) 1 (1) 4 (4) 2 (2) 9 (7) 0 (0) 4 (4) 13496 (13359) 76」
①カッコ内は累計回復者数ということだが、浮沈子は使っていないので、これを手で消していた(かなり面倒くさい)。
②また、改行が4か所ほどあるので、これも消す(手間ではないけど、簡単に出来そうだったので:意外と難航した)。
③最後に、グーグルスプレッドシートに貼り付ける際に、縦書きで(データが縦に並ぶように)行うために整形する。
いろいろネットの記事を読んだんだが、主に参考にしたのは「侍エンジニアブログ」というページ。
やや、宣伝がうるさいけど(プログラミング教室の勧誘)、必要な所だけつまみ食いして撤退したい浮沈子には無縁だ(体系的にプログラミングの勉強をしたことはありません)。
まず、食いついたのは、メインのメソッドであるデータの置き換えをする機能のページ。
(【JavaScript入門】replaceの文字列置換・正規表現の使い方まとめ!)
https://www.sejuku.net/blog/21107
参考にしたコード。
「文字列に含まれているカンマを除去する方法:
var str = '1,234,567';
var result = str.replace(/,/g, '');
console.log( result );」
もう一つ、実際にコピペに使ったもの。
(JavaScriptのreplaceメソッドを使って様々な置換を試してみよう)
https://techplay.jp/column/535
「全角空白・半角空白を削除する:
var sample='吾 輩 は 猫 で ある ';
sample=sample.replace(/\s+/g,'')
console.log (sample)」(\はバックスラッシュ:以下同じ)
浮沈子の開発環境は、エディターはウインドウズのオマケのメモ帳、実行環境はグーグルクロームなので、コンソールとかは使わない(使えばいいのに・・・)。
で、結果を吐き出す先はブラウザーにする。
「document.write(sample) ;」
文字列を効率よく扱うには、正規表現を使うのがいいらしいということで、その辺りのお勉強も。
(【JavaScript入門】4つのパターンで理解する正規表現の使い方まとめ!)
https://www.sejuku.net/blog/20973
参考にした部分。
「「\d」0〜9の数字」
「今回のように数字であれば、「\d」を1つ記述してその後に続けて「*」「+」を書くだけでどんな桁数の数字にもマッチすることになります!」(今回は「*」を使用:カッコ内(累計回復者数)には空文字はないので)
「「time」はそのまま固定で、末尾の「s」に続けて「?」を付けることで、「s」の「ある」「なし」を表すことが出来るのです!」(改行コードのところで「?」が出てきます。)
「正規表現で扱う「特殊文字(. * + ^ | [ ] ( ) ? $ { }など)」は、パターンを作成する時にエスケープしなければいけないケースがあります。」
「正規表現でエスケープ処理を行うのに必要なのは「 (バックスラッシュ)」です」
累計回復者数はカッコ「( )」で囲まれているので、これを正規表現で扱うには、エスケープ処理が必要だからな。
コードを書く(コピペする)上で、MSゴシックだとバックスラッシュが正しく表記されないので、エディターであるウインドウズのメモ帳のフォントを「Arial」に変更しておく。
いろいろ試したんだが、カッコつきの数字(回復者数)を、いきなりブラウザーの改行記号である<br>に置き換えようとすると2回改行されてしまった。
そこで、仮に「p」(文字はテキトーです)で置き換えておいて、「p」をさらに<br>に置き換えることにした(もっとうまいやり方があると思いますけど)。
元データに改行が4か所ほど混ざっているので、これを取り除こうと苦労した。
作成途中では、データをベタ文字列で変数に貼り付けていたので、これを弄ってもうまく置き換えてくれない。
後述の外部ファイルからの読み込みを行って、その内部データに対して置き換えを行ったところ、見事に消えてくれた!。
(【JavaScript入門】文字列を改行する方法(改行コード/「\n」/置換))
https://www.sejuku.net/blog/55631
「改行コードはOSごとに異なります。:
Unix:\r
mac(OS X):\n
mac(OS 9以前):\r
Windows:\r\n」
これらを正規表現で一元的に表記すると、「\r?\n」となるわけだな(ロジカルには「\r?\n?」になるような気も)。
最後は、まあ、順序的には逆なんだが、ローカルのファイルからデータを読み込むところ。
これは、さっぱり分からないので、変数とかもそのままコピペして、置き換え処理のところで入れ替えたりした(禁じ手!)。
(JavaScriptでファイル処理! JSONやCSVなどのファイルを読み込もう)
https://www.sejuku.net/blog/32532
「ファイルの読み込みを実現させるためには、一般的にFile APIを使います。」
「これは、HTML5から利用できるようになった機能(API)になります。JavaScriptからFile APIで提供されているメソッドを組み込むことで簡単にPCのローカルファイルを読み込ませることが可能です。」
簡単とか書いてあるけど、浮沈子には何をやっているのかさっぱりだ。
ここは、そのままコピペして、ファイルの中身を指している変数は、途中で入れ替えるという禁じ手を使ってしまう(スパゲッティープログラミングで、最もやっちまう方法かあ?:良い子はマネしないでね!)。
まあ、そのままでもよかったんですが・・・。
参考にしたコード(つーか、そのままコピペ)。
「<body>
<form name="myform">
<input name="myfile" type="file" />
</form>
<script>
//Form要素を取得する
var form = document.forms.myform;
//ファイルが読み込まれた時の処理
form.myfile.addEventListener('change', function(e) {
//ここにファイル取得処理を書く
})
</script>
</body>」
取得処理のところも、次のコードをそのままコピペした。
「var form = document.forms.myform;
form.myfile.addEventListener( 'change', function(e) {
var result = e.target.files[0];
//FileReaderのインスタンスを作成する
var reader = new FileReader();
//読み込んだファイルの中身を取得する
reader.readAsText( result );
//ファイルの中身を取得後に処理を行う
reader.addEventListener( 'load', function() {
//ファイルの中身をtextarea内に表示する
form.output.textContent = reader.result;
})
})」
説明の意味は、さっぱり分からないが、ちゃんとプログラミングのお勉強している人には簡単なんだろう。
で、試行錯誤を重ねて、出来上がったスパゲッティーナポリタンがこれ・・・。
「<html>
<body>
<form name="myform">
<input name="myfile" type="file" />
</form>
<script>
var form = document.forms.myform;
form.myfile.addEventListener( 'change', function(e) {
var result = e.target.files[0];
//FileReaderのインスタンスを作成する
var reader = new FileReader();
//読み込んだファイルの中身を取得する
reader.readAsText( result );
//ファイルの中身を取得後に処理を行う
reader.addEventListener( 'load', function() {
//②改行除去(ここで、変数の入れ替え!:reader.result→sample)
sample=reader.result.replace(/\r?\n/g,'');
//①カッコ内を仮置き換えpへ(カッコ内を消す処理(その1))
sample=sample.replace(/\(\d*\)/g,'p');
//③仮置き換えpをブラウザー上の改行<br>へ(カッコ内を消す処理(その2)+横書きを縦書きへ)
sample=sample.replace(/p/g,'<br>');
//ファイルの中身をブラウザー上に表示する
document.write(sample) ;
})
})
</script>
</body>
</html>」
①、②、③は、概ね今回の処理でやりたかったことと対応している。
ファイルの選択をもっとシンプルにしたいとか(一応このままでも、クロームでは、ドラッグアンドドロップでも出来ます)、スパゲッティコードを何とかしたいとか、ファイルの読み込みをちゃんと理解したいとか、出力先をブラウザー上ではなく、ファイルにしたいなど課題は山積だが、当初のイメージ通りの仕掛けになったのでいいことにする。
今回の収穫は、これまでちゃんと勉強したことがなかった正規表現について、上っ面だけでも一通り眺めたことだろうな。
開発環境と実装にジャバスクリプトを選んだのは、正解かどうか分からない。
気力と時間が許せば、Jスクリプトは手を付けてみたい気もするし、何より、バッチファイルでさっくり処理したい。
同じことを、異なるプログラミング言語で表現できれば、何となく豊かになった気がするのは、自然言語と同じだ。
メモ帳にコードを書いて、ファイル名にhtml拡張子をつけ、ダブルクリックで起動すると、ブラウザーに画像のタブが出るので、インプットメソッドでPDFから貼り付けたテキストファイルを選ぶだけで、ブラウザーに縦書きの数字が上書きで並び、それをそのままスプシにコピペする。
従来は、PDFから貼り付けたメモ帳で手処理で改行を取り除いたり、区切り文字として入っている半角スペースを入れたり、それらを含めて、半角スペースをタブに置き換えたりという前処理から始まり、作業用のスプシを開き、横書きのまま貼り付けてからコピーし、特殊貼り付け→転置して貼り付けで縦横変換し、1行おきに拾うために0、1で交互にフラグを立てたり並べ替えを行って、ようやく縦書きの累計感染者数だけのデータを得ていた。
改行除去などの前処理もなし、1つおきに拾うこともなし、縦横変換もなし。
PDFからテキストファイルにコピペして、そのまま保存。
デスクトップからジャバスクリプト入りのファイルを起動してタブを開かせ、保存したファイルを選択すれば、整形済みのデータがブラウザー上に展開される。
そのデータ(最初に引用したものと同じ6月2日分)
「851
2612
5301
8783
2401
2969
3224
5307
4710
4404
7854
11712
4666
5221
6430
4260
3648
2604
6064
7148
7425
5496
6861
3943
1326
1278
1512
791
1844
789
1899
2622
930
1113
1148
815
807
426
475
592
454
390
651
367
889
537
343
545
1541
179
105
10
25
23
0
1
1
4
2
9
0
4
13496
76」
それを、集計してグラフ化しているスプシにコピペしてお終い。
時間的には、大した話じゃないけど、毎回毎回、同じ処理を繰り返し行う苦痛が無くなるだけでもマシというものだ。
このブログ記事は備忘のために書いている。
参考に開いたホームページとかは、グーグルに筒抜けだしな。
どーせ筒抜けなんだから、試行錯誤した手順とかも、得意のAIでブログ記事に仕立てて書いて欲しいもんだな。
そうすれば、半徹(半分徹夜)しなくても済んだかもしれないのにな。
今朝は雨。
東京はそれ程でもないけど、西日本は大雨だそうだ。
さて、飯でも食いに行って、爆睡するか・・・。
<以下追加>ーーーーーーーーーー
(JavaScriptのイベントの仕組みが一発で理解できるウェブアプリ「Explore DOM Events」レビュー)
https://gigazine.net/news/20210603-explore-dom-events-javascript/
「JavaScriptには、特定の動作が発生した際にそれに応じてコードを実行する「イベント」という仕組みが存在しています。」
ファイルを読み込んで処理系に渡すときに、どうもイベントドリブンな仕掛けを使っている気がしたので、たまたま読んだギガジンの記事をリンクしておく。
それよりも、この記事からリンクされているチュートリアルは、まあ、英語の直訳だが日本語化されていて、ジャバスクリプトのお勉強には向いている気がする(「イベント」、「DOM」からリンクしている)。
気が向いたら、取り組んでみるのもいいかもしれないな・・・。
<さらに追加>ーーーーーーーーーー
6月5日記。
今日も、フィットネスをサボって、シコシコとプログラミングに勤しむ・・・。
(JavaScript テキストエリアの値を取得/設定する)
https://itsakura.com/js-textarea
考えてみれば、わざわざテキストファイルを経由しなくても、ジャバスクリプトを使うわけだからブラウザー上のテキストエリアに直接コピペした方が簡単に決まっている。
PDFファイルからコピーしたデータは、テキストエリアにペーストすれば、当然テキストデータとして扱われるだろうから(まんまや!)、それをそのままハンドリングすればいい・・・。
で、上記のページを参考に(えーと、例によってコピペしただけですが)茹で上げたスパゲッティーミートソース(ナポリタン改め)が、これ。
「<html>
<body>
<textarea id="textarea3" value="1" cols="140" rows="10" maxlength="1000"></textarea><br>
<input type="button" value="変換" onclick="clickBtn5()" />
<input type="button" value="クリア" onclick="clickBtn7()" />
<script>
function clickBtn5() {
let ta3 = document.getElementById("textarea3").value;
//改行除去
ta3=ta3.replace(/\r?\n/g,'');
//カッコ内を仮変換pへ
ta3=ta3.replace(/\(\d*\)/g,'p');
//仮変換pをブラウザー上の改行へ
ta3=ta3.replace(/p/g,'<br>');
//ファイルの中身をブラウザー上に表示する
document.write(ta3) ;
}
function clickBtn7() {
document.getElementById("textarea3").value = "";
}
</script>
</body>
<html>」(\はバックスラッシュ)
出力は、テキストエリア内でも試してみたんだが(その方がカッコいいし)、半角スペースが残ってしまって上手くいかなかったので、今回はそこは弄らずに、ウェブページ上に変換後のデータを上書きでぶちまける(作業的には、これをスプシのセルにコピペすることになる)。
参考にしたページ上では、クリアボタンが実装されているけれど、サンプルコードでは省略されている。
何とかならんもんか・・・。
「テキストエリアに値を設定する:
・・・
テキストエリアをクリアする場合は、空文字("")をセットします。」
クリアボタンは、これを参考にボタンとファンクションを追加した(ボタンのidとか付けてなかったりして、もう、テキトーです)。
今回は、変数は途中で変えたりしないで同じものを使う。
サンプルプログラムのconstのままだと、書き換え時の再代入を受け付けないので、letにしてみたら動いた(スコープであるfunction clickBtn5()内では再代入も可:もちろん、varでも動きました)。
変数の定義にvar、let、constのどれを使うかについては懇切丁寧な解説のページがあった。
(JavaScriptのletとは?知っておくべき特徴と使い方について)
https://www.sejuku.net/blog/58429
「・varは使わずに、これからはletかconstを利用する
・letは再宣言不可でブロックスコープという特徴がある
・constは再代入も不可だがオブジェクトなどの値は変更可能」
この辺りは、例によってテキトーなので、美しくなくてもいい。
動くプログラムが絶対の正義だからな・・・。
<さらにさらに追加>ーーーーーーーーーー
(今すぐ対策できる!HTMLで文字化けを直す方法【初心者向け】)
https://techacademy.jp/magazine/9929
弄っているうちに、ボタンの表示(「変換」「クリア」)が文字化けしたので対策する。
「HTMLファイルは文字コードUTF-8で保存する。」
「HTMLのmetaタグに charset=”UTF-8″ を指定する。」
「<head>
<title>sample</title>
<meta http-equiv="content-type" charset="UTF-8">
</head>」
こんなことになったのは、またまた改良(?)して、テキストエリアに吐き出すことにしたからか。
ーーーーー<<現在のソースコード:ここから>>ーーーーー
「<html>
<head>
<title>PDF2TXT</title>
<meta http-equiv="content-type" charset="UTF-8">
</head>
<body>
<textarea id="textarea3" value="1" cols="140" rows="10" maxlength="1000"></textarea><br>
<input type="button" value="変換" onclick="clickBtn5()" />
<input type="button" value="クリア" onclick="clickBtn7()" />
<script>
function clickBtn5() {
let ta3 = document.getElementById("textarea3").value;
//元データの改行除去
ta3=ta3.replace(/\r?\n/g,'');
//カッコ内を改行へ
ta3=ta3.replace(/\(\d*\)/g,'\r\n');
//ファイルの中身をテキストエリアに表示する
document.getElementById("textarea3").value = ta3;
}
//テキストエリアのクリア処理
function clickBtn7() {
document.getElementById("textarea3").value = "";
}
</script>
</body>
<html>」
ーーーーー<<現在のソースコード:ここまで>>ーーーーー
今まで仮変換していた「p」とかいう仮文字をやめて、ダイレクトに改行コードを入れた(さすがに、テキストエリアに入れると<br>は、そのまま表示されるからな)。
ウインドウズ環境だから、「\r\n」としたんだが、どうもこれが原因らしい(未確認)。
で、上記のようにヘッドでキャルセットを指定したら、化けなくなった。
随分完成形に近づいている。
ブラウザー経由の処理だが、サーバー上に置いておけば、ネット環境からも使える(ニッチな用途だけど)?
まあ、こんだけだから、メモ帳にコピペして拡張子をhtmlとかにしてからダブルクリックで実行してもいいか・・・。
カッコ内のデータを直接改行コードに変換した際に、半角スペースが付いている感じだったけど(trim()とか使っても、取れませんでした。)、スプシにコピペしてみたら、ちゃんと数値として読み込めたので、このスタイルで行くことにした。
結果が全て。
無事に昨日(6月4日分)のデータもスプシに放り込んで、今日の作業はお終い。
JスクリプトやVBスクリプト、ウインドウズバッチファイルなどでも、同じ様な処理が出来そうだ。
ツールとしては、文字置換は一般的な処理で、テキストファイルに落とし込んでおけば、リプレイスなどと同じようなコマンド(メソッド?)で変換してくれる。
対象とするファイル、置き換え前文字列、置き換え後文字列を指定して、任意の返還をしてくれる汎用ツールのようなものもあった。
(JScript でテキストファイルの文字列を置換する)
https://norastep.hatenablog.com/entry/2015/12/05/205308
「今回は、JScript を用いてテキストファイルの文字列を置換するスクリプトを作りました。」
(windows dosで正規表現の置換が実行可能なツールをつくりました)
http://defmementomori.hateblo.jp/entry/2017/03/17/210144
「正規表現の置換を実行するバッチを組みたい」
「そこでvbsでツールを作りました。」
(バッチファイルでテキストファイル内の文字列置換)
https://knowledge.reontosanta.com/archives/816
「Windowsのバッチファイルでテキストファイル内の特定の文字列を置換する方法」
もちろん、各種開発環境を導入すれば、何でもできるだろう。
ウインドウズの素の環境で、ブラウザー以外の実行環境がない状態では、候補はこれくらいか(パワーシェルとかだと、一発だそうですが)。
今回は、やりたいこと(ニーズ)に特化して、出来ること(シーズ)を選んだ。
Cで書け!とか、パールが最適!とか、パイソンでしょう!とか、浮沈子には皆、敷居が高い。
コードを書いた経験は、DOSのバッチファイル、ベーシック、ジャバスクリプト程度だ。
言語の仕様はどんどん変わっていくから、キャッチアップしないとな。
以前は、ジャバスクリプトで外部ファイルを扱うことはできなかった(浮沈子が知らなかっただけかも)。
HTML5.0から、限られた範囲でのアクセスが可能になり、汎用的な処理にも使えるようになった。
最終的には、PDFからのコピペをテキストエリアに読み込む方法にしたけれど、ファイルの中のデータを弄るという、ドキドキする体験も出来たからな(イベントドリブンな処理の理解は、次回持越しだな)。
ジャバスクリプトは、コンピューターのフロントエンドの処理に大活躍しているようだ。
動的なブラウザーのぺージを作るには欠かせないし、クライアントサイドでのローカル処理で済ませられることを済ませてしまえば、通信コストの削減にも繋がる。
サーバーサイドで動くスクリプトもあるようだ(未確認)。
プログラムと言えば、紙のコード表に手書きして、パンチカードに打ち込んでもらい、光学読み取り機で磁気テープに記録し、夜中にバッチ処理を走らせるものだという時代から付き合っている浮沈子にとって、現代は夢のような時代だ。
掌に乗るスパコンを、ありとあらゆる人々が持ち歩き、溢れるような通信環境で高品位動画を再生して楽しんでいる。
テレビ電話(死語です!)は、新型コロナの時代になって当たり前の存在になり、気の利いた会社はリモートワークに移行して実績を上げている。
そんな時代に、テキストデータのカッコ外して取っ払い、改行コードに置き換えたりして、何が面白いのか・・・。
そのデータが、都内感染者の区市町村別内訳だったりするところが、時代を反映しているわけだ(そうなのかあ?)。
まあ、どうでもいいんですが。
動画も、バーチャルリアリティも結構だけど、コンピューターの基本はテキストデータの処理だ(時代錯誤!?)。
数値を演算したり、テキスト文書を操作したり。
浮沈子は、ブログを書き(大部分コピペし)、たまにプログラムを書き(殆ど全てコピペし)、画像(静止画)を撮って(大体キャプチャかコピペして)楽しんでいる。
今回も、コピペして貼り付け、ワンクリックで成果物を得た(それをまた、コピペして貼り付けるんだがな)。
定型処理を手作業で行うという苦痛から逃れて楽をするために、半徹して突破し、さらに2日掛かりで使いやすくした。
その作業の方が余程骨が折れるが、苦痛ではない。
新しいことを学ぶという、得難い経験をさせてもらえた。
学校のお勉強を楽しいとは思わなかったけど、自分がやりたいことを解決するために、調べたり、人様の知恵を借りたり(=コピペ?:カンニングともいう)することは楽しい。
楽をするための苦労は楽しい。
楽あれば苦あり、苦あれば楽あり。
塞翁が馬ということか・・・。
最近のコメント