2023年11月

我实现了一种文本格式匹配算法,取名FormatExpect。

它看起来长这样。

{[65,90]}[32,32]{[33,126]}[32,32]{[33,126]}[13,13][10,10]{{[65,90;97,122]}[58,58]{[33,126]}[13,13][10,10]}[13,13][10,10]

仔细观察可以发现元素其实只有三种,即花括号、区间和整数。

这个算法的原理为通过匹配文本中指定ascii码区间内的文本判断一段字符串是否符合预定义的格式标准。先从简单的开始说起,请看如下格式文本。

[104,104][101,101][108,108][108,108][111,111]

这是一个单向链式匹配,匹配长度为5的字符串,在此例中,这串文本匹配的是“hello”。104,101,108,108,100分别对应字符串中的hello。

不难发现,每个中括号内的对象对应文本中的一个字符,并且在这种模式中,格式文本顺序和待匹配文本顺序相同。

我现在将其变换为如下形式。

[48,48][120,120][48,57;65,70][48,57;65,70]

前两个元素匹配固定文本0x,后两个元素匹配ascii值区间在[48,57]∪[65,70]中的文本。为了方便起见,我使用分号表示“或”的意思。

所以以上匹配的是合法的两位十六进制数值。

但是这样匹配效率太低,如果文本过长,或不定长,则无法工作。

所以我再次引入结构花括号,代表重复匹配。请看如下例。

{[65,90;97,122]}

不难理解,这匹配的是任意长度由大小写字母组成的字符串。但有一个问题,即如何跳出此循环匹配结构,我们可以这样写。

{[65,90;97,122]}[10,10]{[48,57]}

在循环结构之后添加任意结构(单个匹配元素或另一循环均可),若前一循环最后一位字符匹配成功后下一位字符与循环首位匹配结构不同,但与循环结构之后的一匹配结构相同,即跳出此循环,进入下一结构。

以上匹配文本照此规则,对应的文本为:首行任意数量字母、一换行符\n、第二行任意数量数字。

循环结构可以进行有限次嵌套,举例如下。

{[65,90;97,122][10,10]{[48,57]}}

将最外层循环去掉,可以匹配诸如以下格式的文本。

abcDef
421416

而加入外层循环,代表不限次匹配循环内的格式文本所能成功匹配的结构。

abcDef
421416
iLoveCProgrammingLangrage
123456
...

规则就这么多。现在回头看本文开篇所写的格式文本,你能猜出这匹配的是什么吗?

1

你可以在逸隐的FormatExpect仓库下载其源码,我在这里简单解释一下实现原理。
fexp_build_tree函数将一串FormatExpression文本解析为一颗匹配树,fexp_match_text函数同时遍历树和待匹配文本的每个Char,当匹配树同一深度的所有节点都无法满足待匹配文本的下一字符时,则匹配失败。当匹配树已经被遍历到叶子节点而没有出现匹配失败的情况,则成功匹配。

癸卯年八月廿九,周末独自乘火车前往老君山游玩,在此记录我的经历和部分照片。

今天是2023年11月6号,此篇拖了大半个月终于开始动笔。

游玩之前我通过贴吧和小红书等平台查询攻略,原定周六中午乘坐高铁从西安前往洛阳、大巴车到老君山景区后夜爬上山,但考虑到晚上气温较低,独行各种不方便等等,遂放弃,于是预定周五晚的火车卧铺出发,提前在携程预定当晚到第二天下午的车站酒店,凌晨一点到达洛阳站后在酒店休息到周六中午,接着乘坐花都客运站洛阳往返栾川的高速大巴到景区。

栾川县城遥望老君山只觉山峰高耸入云巅,飘逸如梦翔鸟天。和一路上洛栾高速旁的小山丘相比,此山给我极其震撼、与众不同的感觉,以至于不看地图,就可断定这必然是此行的目的地。我游玩过的名山不在少数,但却鲜有能与之相比的。

景区开发十分完善,门票和缆车都可通过公众号预定。从游客中心乘坐两趟观光车可直接到达云景索道入口。但我个人不建议乘坐第一趟5元一次的观光车到景区大门,百米之遥步行即可到达。

票务中心
景区大门

我的安排是周六晚上在山上过夜,圆我使用手机拍摄星空的愿望,周日早上观看日出后下山回洛阳市区。

随便挑的周末以为人会少一些,结果人潮依旧,但相比刚刚过去的国庆假期,还是好了不止一星半点。

缆车入口
山顶阶梯

一级索道可以直接到达中天门,当然自驾也可以乘车直达。山门前有老子骑牛雕像,大部分山上的景观酒店也建立在中天门一旁的山壁之上。远观过去,全透明玻璃客房、钢结构框架与山体的结合颇有现代和自然的融合之妙。

从山门进入,直接就是坡度陡峭的多级向上的台阶,颇有华山千尺幢的感觉,但自然是不如后者险绝。

中天门
遥望金顶
奇石
峰
烤肠
许愿牌

老君山的许愿牌可被誉为一特色。不同于被人们胡乱锁系的请愿条和同心锁,红色的木牌挂在松树的枝条上,显现出独特的人文自然之美。

十里画屏是老君山最值得欣赏的景观,隐约间有华山的气韵在内。山崖和绝壁,是八百里伏牛山脉的招牌。

山崖
峡谷
3
4
5

碧山绿林红枫秀, 独立高峰映夕阳。

层峦叠嶂
无题
无题
无题
无题

绵延千里的栈道让我有种神奇的感觉。

祈福
无题
电梯入口
无题

最终通过电梯赶在天色彻底暗下来之前到达了金顶。黛蓝色的天空与金色的灯光交相辉映,营造了天上人间的氛围。

傍晚山巅金光映,

楼阁璀璨似仙城。

无题
无题
金殿

晚上山顶真的很冷,庆幸自己没有选择夜爬上山。

原本打算在山顶露宿的,结果实在受不了寒风凛冽,只能花重金入住山顶青年旅社。

山顶敲代码

从哈尔滨带回来的JEEP手提袋,在将无人机和大衣带上山顶后光荣阵亡。

JEEP

以下是我在深夜冒着寒风出门通过长曝光拍的几张星空照片。由于手机支架质量低劣,加上华为MATE50本身相机性能限制,效果不尽如人意。

星空下的金殿
伏牛山脉的星空
无题

第二天五点不到早起观看日出,举着支架拍了一个小时的延时视频,手已经冻成冰块。

无题
myvideo
无题
无题
无题
无题

运气不错,虽然没有云海,但也不至于拍的全是些云里雾里的照片。

最后以我在金顶吃泡面的剪影作为我老君山之行的结尾。

泡面!

愚见以为老君山相比五岳有过之而无不及,只有亲身至此,才有机会体验那"远赴人间惊鸿宴,一睹人间盛世颜"的壮丽景色和博大精深的文化底蕴。