首页 > 代码库 > 《Python基础教程》第20章学习笔记

《Python基础教程》第20章学习笔记

python实现:https://github.com/captainwong/instant_markup

c++实现:https://github.com/captainwong/instant_markup_cpp

要点:

1.标准输入输出流的重定向

python markup.py < test_input.txt > test_output.html

上述命令将标准输入设备重定向为文件input.txt,将标准输出设备重定向为文件test_output.html。

Python中使用的标准输入设备为sys.stdin, 输出使用函数print。C语言使用stdin和函数printf等。c++使用cin。 cout。


2.使用字符串调用函数

如依据字符串"foo"查找函数foo并调用之。

def callback(self, prefix, name, *args):
	method = getattr(self, prefix+name, None)
	if callable(method):	return method(*args)
	
def start(self, name):
	self.callback(‘start_‘, name)
	
def end(self, name):
	self.callback(‘end_‘, name)
	
def sub(self, name):
	def substitution(match):
		result = self.callback(‘sub_‘, name, match)
		if result is None: match.group(0)
		return result
	return substitution


使用时可通过调用

start(‘document‘)

来调用start_document函数。



c++无此特性。这里我使用map保存函数名和函数指针的方法来模拟这样的功能。

首先定义函数指针:

typedef void (CHandler::*pFunc)();

定义静态map成员:

static map<string, pFunc> m_funcmap;

使用宏定义简化初始化操作:

#define STR(str) #str
#define ASSIGN_FUNC(func_name) 	CHandler::m_funcmap[STR(func_name)] = (CHandler::pFunc)&func_name;

初始化:

CHTMLRenderer::CHTMLRenderer()
{
	ASSIGN_FUNC(CHTMLRenderer::start_document);
	ASSIGN_FUNC(CHTMLRenderer::end_document);
	ASSIGN_FUNC(CHTMLRenderer::start_paragraph);
	ASSIGN_FUNC(CHTMLRenderer::end_paragraph);
	ASSIGN_FUNC(CHTMLRenderer::start_heading);
	ASSIGN_FUNC(CHTMLRenderer::end_heading);
	ASSIGN_FUNC(CHTMLRenderer::start_list);
	ASSIGN_FUNC(CHTMLRenderer::end_list);
	ASSIGN_FUNC(CHTMLRenderer::start_listitem);
	ASSIGN_FUNC(CHTMLRenderer::end_listitem);
	ASSIGN_FUNC(CHTMLRenderer::start_title);
	ASSIGN_FUNC(CHTMLRenderer::end_title);
	ASSIGN_FUNC_SUB(CHTMLRenderer::sub_emphasis);
	ASSIGN_FUNC_SUB(CHTMLRenderer::sub_url);
	ASSIGN_FUNC_SUB(CHTMLRenderer::sub_mail);
}


调用方法:
void CHandler::callback(const string &str)
{
	funcmap_iter iter = m_funcmap.find(str);
	if(iter != m_funcmap.end())
		(this->*(iter->second))();
	else
		cout << "invalid function name : " << str << endl;
}

void CHandler::start(const string &func_name)
{
	callback(string("CHTMLRenderer::start_") + func_name);
}

void CHandler::end(const string &func_name)
{
	callback(string("CHTMLRenderer::end_") + func_name);
}

3.使用正則表達式

Python标准库提供了re包来进行正則表達式的处理。而c++标准库没有实现regex,boost::regex功能强大,但为了写一个小demo,包括一大堆库太麻烦。

我使用一个轻量级的开源c++实现正则库deelx。官网: http://www.regexlab.com/

整个库就是一个头文件deelx.h,使用时include之就可以。

演示样例:

string filtering(const string& block, const string& pattern,
				const string& sub_name, CHandler* handler){
	static CRegexpT <char> regexp;
	regexp.Compile(pattern.c_str());
	MatchResult result = regexp.Match(block.c_str());
	if(result.IsMatched()){
		char* content = regexp.Replace(block.c_str(),
			handler->sub(sub_name).c_str());
		string new_block(content);
		regexp.ReleaseString(content);
		return new_block;
	}
	return block;
}
deelx源代码与文档可在其官网下载。



结果例如以下图:

技术分享

《Python基础教程》第20章学习笔记