我正在研究游戏分析软件,我必须将句子转换成我称之为“句子模板”的句子,并将这些句子模板与存储在Excel工作表中的标准模板相匹配。根据是否找到匹配,可以采取一些措施。整个程序都在Excel-VBA中。
例如,如果句子是:
传球左侧平坦的T.Harry最近的后卫
相应的句子模板是:
传球$ DIR $ flat $ NAME $ nearest defender
因此,句子模板用我称之为“面具”的句子替换句子中的“变量”单词。因此,$ DIR $可以表示“左”,“右”或“中心”,它仍然代表相同的句子模板。同样地,G.Jones可以取代T.Harry,它仍然是相同的模板。
除了$ DIR $和$ NAME $之外,还有大约六种不同类型的面具被使用。大约有1200个标准模板。
掩蔽是通过一个不能100%万无一失的程序完成的,因为掩盖的单词,特别是名称,有很多变化。例如,T.Harry可以简称为Harry或T. Harry(中间有空格)或Tom Harry。我需要有一些方法来确定如果句子中的所有其他单词与除了掩码之外的1200个模板中的任何一个的单词匹配。如果发生这种“LIKE”匹配,则很可能是相同的句子模板,并且只要满足某些其他过滤条件,就可以将其视为具有高置信度的相同句子模板。
面具可以出现在句子中的任何位置,并且没有任何固定的位置。
我的方法(我认为这种方法效率低,而且是蛮力)
a)使用分割功能
将1200个标准句子模板中的每一个分割成单词b)将要比较的句子拆分为使用拆分功能的单词
c)使用以下逻辑
将“b”中的单词与循环中的1200个模板中的每一个匹配d)将句子模板中的匹配单词与标准句子模板中的单词保持一致,直到一个单词不匹配。如果单词不匹配,请跳过该单词并继续下一个单词。保持匹配,直到非匹配的单词超过掩码的数量。
e)如果非匹配单词超过掩码数,则很可能不是同一个句子。
f)如果非匹配的单词等于或小于掩码的数量,除了掩码,所有其他单词都匹配,那么具有高置信度就是相同的句子模板。
有更好的方法吗?有没有办法找到哪个是第一个字符,其中两个字符串不匹配或显示分歧。
帮助表示感谢。截至目前,我已经在句子不匹配时寻求人工干预,但如果上述逻辑有效,那就太棒了。提前谢谢。
答案 0 :(得分:0)
如何在模板中使用正则表达式(例如^Pass thrown .*? flat .*? closest defender$
),然后在VBA中运行这些表达式...
您可以在VBA中使用正则表达式(示例函数):
Function RegExpTest(ByVal repattern As String, ByVal value As String)
' does a regular expression search for "repattern" in string "value"
' returns the match
' or "" if not found
Dim RegEx As Object
' create the RegExp Object with late binding
Set RegEx = CreateObject("vbscript.regexp")
With RegEx
.Global = True 'look for global matches
.Pattern = repattern
End With
RegExpTest = RegEx.Test(value)
Set RegEx = Nothing
End Function
它仍然不会打破任何速度记录,但比分割方法更简单快捷(特别是在名称可以有空格的情况下 - 正则表达式将处理那么好)
修改强>
在示例函数中,repattern
是传入的字符串(例如,来自工作表函数调用)。 repattern
同样可以设置为单元格的值 - 即您的模式存储在工作表的单元格中
因此,对于每个输入字符串,您可以遍历包含正则表达式模式的工作表范围并测试字符串以查找匹配项,如果找到匹配项则会中断循环。
在从模板制作模式方面,如果所有模板都遵循格式$SOMETHING$
,您可以使用正则表达式进行替换,使模板成为模式:-)使用VBA中的以下函数,在您的工作表中,您将放置公式=REGSUB("\$.*?\$",A1,".*?")
!享受!
Function RegSub(ByVal repattern As String, ByVal value As String, ByVal replacement As String) As String
RegSub = value
Dim RegEx As Object
Set RegEx = CreateObject("vbscript.regexp")
With RegEx
.Global = True 'look for global matches -> replace all
.Pattern = repattern
End With
RegSub = RegEx.Replace(value, replacement)
Set RegEx = Nothing
End Function