XL_TEST_CASE()
{
RegExp r;
// IPv4 address
XL_TEST_ASSERT(r.Parse(L"("
L"(0|1|2|3|4|5|6|7|8|9)|"
L"(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)|"
L"(0|1)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)|"
L"2(0|1|2|3|4)(0|1|2|3|4|5|6|7|8|9)|"
L"25(0|1|2|3|4|5)"
L").("
L"(0|1|2|3|4|5|6|7|8|9)|"
L"(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)|"
L"(0|1)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)|"
L"2(0|1|2|3|4)(0|1|2|3|4|5|6|7|8|9)|"
L"25(0|1|2|3|4|5)"
L").("
L"(0|1|2|3|4|5|6|7|8|9)|"
L"(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)|"
L"(0|1)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)|"
L"2(0|1|2|3|4)(0|1|2|3|4|5|6|7|8|9)|"
L"25(0|1|2|3|4|5)"
L").("
L"(0|1|2|3|4|5|6|7|8|9)|"
L"(0|1)(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9)|"
L"2(0|1|2|3|4)(0|1|2|3|4|5|6|7|8|9)|"
L"25(0|1|2|3|4|5)"
L")"));
XL_TEST_ASSERT(r.Match(L"192.168.1.1"));
XL_TEST_ASSERT(r.Match(L"0.0.0.0"));
XL_TEST_ASSERT(r.Match(L"255.255.255.255"));
XL_TEST_ASSERT(!r.Match(L"0.0.0.256"));
}
小结
本文构造了正则表达式解析器的一个基本框架,并且完成了对“|”“(”“)”这三个操作符的语法分析。在这里,我们确定了基本的数据结构和算法,以后将在此基础上扩展,实现更多的功能。
本文中定义的节点结构和边结构,只适用于目前的需求,以后如果满足不了需要,将会修改。本文所使用的 xl::Graph 功能也并不完善,以后也会同步修改。本文使用ε-NFA直接进行匹配检验,检验的时候使用了较多的递归,性能上并没有达到比较优化的状态,这将在未来某篇中讨论。在最初的几篇中,我们将着重于实现一些必要的功能。
本文中涉及的实现代码在:
http://xllib.codeplex.com/SourceControl/changeset/view/16815#270275
单元测试代码在:
http://xllib.codeplex.com/SourceControl/changeset/view/16815#270901
欢迎探讨、批评、指正。
摘自 溪流漫话