nodejs で百本ノックを受けてみる 第3章

たまたま 見かけた 言語処理100本ノック2015。せっかくなので 勉強中のnodejsで試してみる
環境は Win[7|10] Pro x64 と node.js の 8.x系
コードがクズなのは、JSも勉強中だから ということで
次に第3章: 正規表現

20. JSONデータの読み込み
Wikipedia記事のJSONファイルを読み込み,「イギリス」に関する記事本文を表示せよ.問題21-29では,ここで抽出した記事本文に対して実行せよ.


var async = require('async');
var fs = require('fs');
async.forEachSeries(fs.readFileSync('jawiki-country.json','utf8').toString().split('\n'), function (line, cb) {
if (line.length > 0 ) {
var obj = JSON.parse(line);
if (obj.title == 'イギリス') {
fs.appendFileSync('UK.txt', obj.text , 'utf8');
}
}
cb();
}, function() {
console.log('end');
});

21. カテゴリ名を含む行を抽出
記事中でカテゴリ名を宣言している行を抽出せよ.(これでいいのかな?)


var async = require('async');
var fs = require('fs');

async.forEachSeries(fs.readFileSync('UK.txt',
'utf8').toString().split('\n'), function (line, cb) {
if (line.length > 0 ) {
if (line.match(/\[\[/)) {
console.log(line);
}
}
cb();
}, function() {
console.log('end');
});

22. カテゴリ名の抽出
記事のカテゴリ名を(行単位ではなく名前で)抽出せよ.
リカーシブで書くべきなんだけど、promise版でどう書けば良いのか現在 わからない・・
\[\[ が入れ子になってるところは、現在抜いているんだけど、どっちが正解なのかね??


var async = require('async');
var fs = require('fs');

async.forEachSeries(fs.readFileSync('UK.txt', 'utf8').toString().split('\n'), function (line, cb) {
if (line.length > 0 ) {
if (line.match(/\[\[/)) {
let lv = 0;
let out2 = '';
let out4 = '';
for (let i = 0; i < line.length; i++) {
if (line[i] == '[') {
lv = lv + 1;
if (lv == 2) {
out2 = '';
} else if (lv == 4) {
out4 = '';
}
} else if (line[i] ==']') {
lv = lv - 1;
if (lv == 0) {
fs.appendFileSync('UK2.txt', out2 + '\n', 'utf8');
out2 = '';
} else if (lv == 2) {
fs.appendFileSync('UK2.txt', out4 + '\n', 'utf8');
out4 = '';
}
} else if ( lv == 2 ) {
out2 = out2 + line[i];
} else if ( lv == 4) {
out4 = out4 + line[i];
}
}
}
}
cb();
}, function() {
console.log('end');
});

23. セクション構造
記事中に含まれるセクション名とそのレベル(例えば"== セクション名 =="なら1)を表示せよ.
これもリカーシブで書くべきコードだよなぁ・・


var async = require('async');
var fs = require('fs');
async.forEachSeries(fs.readFileSync('UK.txt', 'utf8').toString().split('\n'), function (line, cb) {
if (line.length > 0 ) {
if (line.match(/^==(?!=).*==$/)) {
console.log("1. " + line.replace(/=/g, ''));
} else if (line.match(/^===(?!=).*===$/)) {
console.log("2. " + line.replace(/=/g, ''));
} else if (line.match(/^====(?!=).*====$/)) {
console.log("3. " + line.replace(/=/g, ''));
}
}
cb();
}, function() {
console.log('end');
});

26. 強調マークアップの除去
25の処理時に,テンプレートの値からMediaWikiの強調マークアップ(弱い強調,強調,強い強調のすべて)を除去してテキストに変換せよ(参考: マークアップ早見表).(単体で作ってみる)


// 対象は以下で良いのかな??
// 斜字体 ''弱い強調'' 弱い強調
// 太字 '''強調''' 強調
// 太字+斜字体 '''''強い強調''''' 強い強調
//
var async = require('async');
var fs = require('fs');
let fileName = './RES.txt';
//fs.access(fileName, (err) => {
// if (!err) {
// fs.unlinkSync(fileName);
// }
//});
let pos = 0;
async.forEachSeries(fs.readFileSync('UK.txt', 'utf8').toString().split('\n'), function (line, cb) {
if (line.length > 0 ) {
if (line.match(/''(?!').*''/)) {
pos = line.indexOf("'''''", 0);
while (pos != -1) {
line = line.replace(/'''''/, ' ');
pos = line.indexOf("'''''", pos + 1);
}
pos = line.indexOf("'''", 0);
while (pos != -1) {
line = line.replace(/'''/, ' ');
pos = line.indexOf("'''", pos + 1);
}
pos = line.indexOf("''", 0);
while (pos != -1) {
line = line.replace(/''/, ' ');
pos = line.indexOf("''", pos + 1);
}
}
//console.log(line);
fs.appendFileSync(fileName, line + '\n', 'utf8');
} else {
//console.log('\n');
fs.appendFileSync(fileName, '\n', 'utf8');
}
cb();
}, function() {
console.log('end');
});