C++ Builder CE ネットワークプログラミング

スクリプトじゃなくてアプリケーションで正規表現を使う方が柔軟ですよ

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

コメント