Poco::RegularExpression

Poco::RegularExpression を紹介します。

その名の通り正規表現を扱うクラスで、Philip Hazel さん作の PCRE という Perl コンパチブルな正規表現ライブラリを使って実装されています。 (http://www.pcre.org).

RegularExpressionTest.cpp

・正規表現そのものを解説してもしょうがないので何を作ろうか迷ったのですが、
 Poco::RegularExpression のページのソースからキーワードを抽出して、Cross Reference のページの
 ような表を作る(HTML ファイルを吐き出す)ことにしました。
・まず “<a name=\”[0-9]+\”>[A-Za-z]+</a>” で切り出して、その文字列から “[0-9]+” で番号を、
 ”[A-Za-z]+” で method/enum 名を抽出してハイパーリンクを作成。
・それに続く説明文を “(description\”>\n<p>)(.*)(</p>)” で抜き出し。

#include <Poco/Format.h>
#include <Poco/Net/HTTPStreamFactory.h>
#include <Poco/FileStream.h>
#include <Poco/StreamCopier.h>
#include <Poco/URI.h>
#include <Poco/URIStreamOpener.h>
#include <Poco/RegularExpression.h>
#include <Poco/String.h>
 
#include <string>
#include <sstream>
 
#include "ScopedLogMessage.h"
#include "PrepareConsoleLogger.h"
 
const char* kOutputFileName = "RegularExpression.html";
const char* kSourceFileName = "http://pocoproject.org/docs/Poco.RegularExpression.html";
 
const char* LeadingHTML =
	"<!DOCTYPE html PUBLIC '-//W3C//DTD XHTML 1.0 Transitional//EN' 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd'>\n"
	"<html xmlns='http://www.w3.org/1999/xhtml'>\n"
	"<head>\n"
	"<title>Class Poco::RegularExpression</title>\n"
	"</head>\n"
	"<body>\n"
	"<table border='1'>\n"
	"<th>Method/Enumeration</th><th>Description</th>\n";
 
const char* TrailingHTML =
	"</table>\n"
	"</body>\n";
 
int main(int /*argc*/, char** /*argv*/)
{
	PrepareConsoleLogger logger(Poco::Logger::ROOT, Poco::Message::PRIO_INFORMATION);
 
	ScopedLogMessage msg("RegularExpressionTest ", "start", "end");
 
	{
		Poco::FileOutputStream ostr(kOutputFileName);
 
		ostr << LeadingHTML;
 
		Poco::Net::HTTPStreamFactory::registerFactory();
		Poco::URI uri(kSourceFileName);
		try
		{
			std::auto_ptr<std::istream> pStr(Poco::URIStreamOpener::defaultOpener().open(uri));
			std::stringstream ss;
			Poco::StreamCopier::copyStream(*pStr.get(), ss);
 
			msg.Message(Poco::format(" Finding out methods/enumerations from \"%s\".", std::string(kSourceFileName)));
			Poco::RegularExpression re("<a name=\"[0-9]+\">[A-Za-z]+</a>");
			Poco::RegularExpression::Match match;
			match.offset = 0;
			while(0 != re.match(ss.str(), match.offset, match))
			{
				std::string foundStr(ss.str().substr(match.offset, match.length));
 
				std::string numStr;
				Poco::RegularExpression re_num("[0-9]+");
				re_num.extract(foundStr, 0, numStr);
 
				std::string nameStr;
				Poco::RegularExpression re_name("[A-Za-z]+");
				re_name.extract(foundStr, std::strlen("<a name=\"\">")+numStr.length(), nameStr);
 
				msg.Message(Poco::format("  found \"%s\"", nameStr));
 
				ostr << "<tr><td><a href='" << uri.toString() << "#" << numStr << "' target='_blank'>"
					 << nameStr << "</a></td>";
 
				std::string descStr;
				Poco::RegularExpression re_desc("(description\">\n<p>)(.*)(</p>)");
				Poco::RegularExpression::Match match_desc;
				if(re_desc.match(ss.str(), match.offset, match_desc))
				{
					descStr = ss.str().substr(match_desc.offset, match_desc.length);
					re_desc.subst(descStr, "$2");
					Poco::replaceInPlace(descStr, "\"", "'");
					Poco::replaceInPlace(descStr, "href='Poco.", "href='http://pocoproject.org/docs/Poco.");
				}
				ostr << "<td>" << descStr << "</td></tr>" << std::endl;
 
				match.offset += match.length;
			}
		}
		catch(Poco::Exception& exc)
		{
			msg.Message(exc.displayText());
		}
 
		ostr << TrailingHTML;
	}
	msg.Message(Poco::format(" HTML file \"%s\" created.", std::string(kOutputFileName)));
 
	return 0;
}

Results of execution

[0] RegularExpressionTest start
[0]  Finding out methods/enumerations from "http://pocoproject.org/docs/Poco.RegularExpression.html".
[0]   found "MatchVec"
[0]   found "Options"
[0]   found "RegularExpression"
[0]   found "extract"
[0]   found "extract"
[0]   found "match"
[0]   found "match"
[0]   found "match"
[0]   found "match"
[0]   found "match"
[0]   found "match"
[0]   found "split"
[0]   found "split"
[0]   found "subst"
[0]   found "subst"
[0]   found "substOne"
[0]  HTML file "RegularExpression.html" created.
[0] RegularExpressionTest end

・実行時に作成される HTML ファイル RegularExpression.html をブラウザで開いたイメージ:
screen shot

Downloads

ここをクリックすると、makefile や VC++ プロジェクトなど一式がダウンロードできます。
(2013.05.31 updated)
・2010年6月16日からのダウンロード数:829

Subversion

・フリーの Subversion ホスティングサービス Assemblaで、ソースコードを管理しています。

Reference

Regular Expression(Riue ちゃんの正規表現講座) – Index
http://pocoproject.org にある StringsAndFormatting のプレセンテーション。(PDF)

Powered by POCO Copyright © 2010 Round Square Inc. All rights reserved.


  1. i try it with win/xp + vs9 + poco 1.6.1 and it does not find the text with “regex”. 🙁

Leave a Comment


NOTE - You can use these HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>