スクリプトじゃなくてアプリケーションで正規表現を使う方が柔軟ですよ
curlとjqとffmpegを使ってNHKらじる聞き逃しのストリームを録音するスクリプトという前記事
で最初のマスターインデックスから”ラジオ英会話”の最新のストリームを得るbashスクリプトについて書きましたが、それをアプリケーションでやります。4月新年度でラジオの英会話をリスタートしようという方も多くいらっしゃるということで、アプリの方が楽です。使うのはね。アプローチはスクリプトでもアプリでの途中まで一緒ですが、アプリの場合は”正規表現”でのフィルタリングができます。具体的なコードを示します。ご希望があれば、Githubのパブリックレポジトリで公開しますので、その旨コメント願います。さて、
void __fastcall TForm1::FilterClick(TObject *Sender)
{
AnsiString url = "https://www.nhk.or.jp/radio-api/app/v1/web/ondemand/corners/new_arrivals";
TMemoryStream* ms = new TMemoryStream(); //
TStringList* atlist = new TStringList();
if( !jsonstuffed ){
jsonorig = "";
try {
IdHTTP1->Get(url,ms);
}
catch(const Exception& e)
{
ShowMessage(e.ClassName());
return;
//printf("Caught C++ Exception: %s :\n", e.msg());
}
ms->Position = 0;
atlist->LoadFromStream(ms, TEncoding::UTF8);
jsonorig="";
for( int i = 0 ; i < atlist->Count ; i++ ){
jsonorig += atlist->Strings[i];
//Memo1->Lines->Add(atlist->Strings[i]);
}
jsonstuffed = true;
}
LStringReader = new TStringReader(jsonorig);
LJsonTextReader = new TJsonTextReader(LStringReader);
LIterator = new TJSONIterator(LJsonTextReader);
int i = 0;
int j = 0;
ListBox2->Items->Clear();
for(;;){
String target = "corners[" + IntToStr(i) + "]";
if( !LIterator->Find(target) )
break;
else
LIterator->Recurse();
while(LIterator->Next()){
bool found = false;
int temp = LIterator->AsInteger;
LIterator->Next();
if( TRegEx::IsMatch(LIterator->AsString,ComboBox1->Text )){ // match
found = true;
name[j] = LIterator->AsString; // name saved
}
LIterator->Next();
LIterator->Next();
LIterator->Next();
LIterator->Next();
LIterator->Next();
if( found ){
ids[j] = LIterator->AsString;
}
LIterator->Next();
if( found ){
site_ids[j] = LIterator->AsString;
j++;
}
if( found ){
entry[j] = {ids[j-1],site_ids[j-1]};
ListBox2->AddItem(name[j-1],reinterpret_cast<TObject*>(&entry[j]));
}
if( LIterator->Type == TJsonToken::StartObject )
LIterator->Recurse();
if( LIterator->Type == TJsonToken::StartArray )
LIterator->Recurse();
if( LIterator->Type == TJsonToken::EndObject )
LIterator->Return();
if( LIterator->Type == TJsonToken::EndArray )
LIterator->Return();
if( LIterator->Type == TJsonToken::EndArray && LIterator->Depth > 0 )
LIterator->Return();
}
i++;
}
Label8->Caption = IntToStr(ListBox2->Items->Count);
Form1->IdHTTP1->Disconnect();
if( ListBox2->Items->Count == 1 ){ // just one program then go dbl click it
ListBox2->Selected[0] = true;
ListBox2DblClick(Sender);
//ここでいいけど、latestのpick upせんとね。
if( AutoPlay->Checked ){
ListBox1->Selected[ListBox1->Items->Count-1] = true;
ListBox1DblClick(Sender);
}
}
}
ここで肝心要(かんじんかなめ)の正規表現によるサーチは、
if( TRegEx::IsMatch(LIterator->AsString,ComboBox1->Text )){ // match
//ListBox2->Items->Add(LIterator->AsString);
//ids[j] = temp;
found = true;
name[j] = LIterator->AsString; // name saved
}
この部分です。ComboBox1->Textは正規表現パターンで、それとLIterator->AsStringの一致を見ています。TRegEx::IsMatch()のおかげさまです。アプリのバイナリは、vectorにありますので使ってみてくださいね。https://www.vector.co.jp/soft/dl/winnt/net/se526599.html
コメント