使用MS Access 2010和VBA(叹息..)
我正在尝试实现一个专门的Diff函数,它能够根据更改的内容以不同的方式输出更改列表.我需要能够生成一个简明的更改列表,以便为我们的记录提交.
我想使用诸如< span class =“references”>之类的html标签之类的东西.这些是引用1,6< / span>这样我就可以用代码查看更改并自定义更改文本的输出方式.或其他任何东西来完成我的任务.
我认为这是一种提供自定义输出的可扩展方式的方法,并可能将事物移动到更强大的平台并实际使用html / css.
有谁知道一个类似的项目可能能指出我正确的方向?
我的任务
我有一个访问数据库,其中包含工作操作指令表 – 通常是200-300个操作,其中许多操作正在从一个修订版更改为另一个修订版.我目前已经实现了一个函数,它遍历表,查找已更改的指令并进行比较.
请注意,每个操作指令通常是几个句子,最后有几行,带有一些文档引用.
我的算法基于“An O(ND) Difference Algorithm and Its Variations”,效果很好.
Access支持“Rich”文本,这只是美化简单的html,因此我可以轻松生成带有格式化添加和删除的全文,即添加像< font color =“red”>< strong>< i>此文字已被删除< / i>< / strong>< / font>. Diff过程的主要输出是操作的全文,其中包括彼此内联的未更改,已删除和插入的文本. diff程序添加< del>和< ins>稍后用格式化文本替换的标记(结果类似于堆栈交换编辑的更改视图).
但是,就像我说的,我需要以人类可读格式列出的更改.事实证明这很困难,因为许多变化产生了模糊性.
例如:如果某种化学品从“A类”变为“C类”,则容易生成的更改文本是“将’A’更改为’C’”,这对于审核该类型的人来说并不是非常有用.变化.更常见的是最后的文档参考:将SOP 3添加到列表中,例如“SOP 1,2,3”,生成文本“添加’3’”.显然也没用.
最有用的是指定为“SOP”文本的文本的自定义输出,以便输出为“添加对SOP 3的引用”.
我从以下解决方案开始:
将单词组合在一起将诸如“SOP 1,3”之类的文本作为一个标记进行比较.这将生成文本“将’SOP 1,2’改为’SOP 1,3′.当有一个大型列表并且您正在尝试确定实际更改的内容时,这会变得混乱.
我现在在哪里
我现在正在尝试在运行diff算法之前添加额外的html标签.例如,我将通过“预处理器”运行文本,将“SOP 1,2”转换为SOP 1,2
一旦Diff过程返回完整的更改文本,我会浏览它,注意文本的当前“类”,并且当有< del>时或者< ins>我捕获标签之间的文本,并在类上使用SELECT CASE块来解决每个更改.
这实际上在大多数情况下都可以正常工作,但是我必须解决许多问题,例如添加Diff决定最短路径是删除某些开放标记并插入其他开放标记.这会创建一个场景,其中有两个< span>标签,但只有一个< / span>标签.
最终的问题
我正在寻找建议,要么继续我已经开始的方向,要么在将更多时间投入到次优解决方案之前尝试不同的方法.
提前谢谢.
另请注意:
典型运行的时间大约是1.5到2.5秒,我尝试了更多花哨的东西和一堆debug.prints.因此,通过一两个额外的通行证不会成为杀手.
解决方法
SOP i1,i2,... iN -> SOP j1,SOP j2,... SOP jN where j = sorted(i)
换句话说,在以下整数的排序列表上“分配”SOP.这将欺骗diff算法提供完全合格的更改报告“添加SOP 3”.
通过在输入中搜索左侧的匹配并用相应的右侧替换来应用规则.
您可能已经这样做了,但如果输入被标记化,您将获得更多常识分析:“SOP”应该被视为diff算法的单个“字符”.如果空格很重要或被忽略,则空格可以缩减为空格和换行符令.
您可以在角色级别执行另一种差异来测试令牌的“模糊”相等性,以便在匹配左侧时考虑到印刷错误. “SIP”和“SOP”将被计为“匹配”,因为它们的编辑距离仅为1(并且在QUERTY键盘上I和O只相隔一个键!).
如果你考虑输出中你现在得到的所有怪癖并且可以将每一个作为重写规则来纠正,将输入转换为diff算法产生你需要的形式,那么剩下的就是实现重写系统.以一般有效的方式执行此操作,以便更改和添加规则不涉及大量的临时编码是一个难题,但已经研究过.有趣的是,@ Ira Baxter提到了lisp,因为它擅长于此类工具的工具.
Ira对语法树的建议自然属于重写规则方法.例如,假设SOP有部分和段落:
SOP 1 section 3,paras 2,1,3
是一个应该重写为的层次结构
SOP 1 section 3 para 1,SOP 1 section 3 para 2,SOP 1 section 3 para 3
重写规则
paras i1,... iN -> para j1,para j2,... para jN where j = sorted(i) section K para i1,... para iN ->s section K para j1,... section K para j1 SOP section K para i1,... section K para i1 -> SOP section K para j1,... SOP section K para j1
当在三次通过中应用时将产生类似“SOP 1第3节,第4段被添加”的结果.
虽然有很多策略来实现规则和重写,包括将每个规则编码为VB中的过程(argh …),但还有其他方法. Prolog是尽可能普遍地做到这一点的盛大尝试. There is a free implementation.还有其他人.我用TXL来完成有用的重写. TXL唯一的问题是它假设你对输入有一个相当严格的语法,这听起来不像你的问题.
如果您在当前输出中发布更多关于怪癖的示例,我可以通过更多有关重写规则的详细信息来跟进.