我有一个场景,我想在其中已经有通配符的字符串上使用通配模式进行搜索。用我的话来说,我会说这是一种双向模式匹配要求。
输入和模式字符串可以包含以下任一/两个通配符 - ?表示单个字符,%表示零个或多个字符。假设这些是输入和模式字符串中允许的唯一2个通配符。
例如:
bool IsMatch(字符串输入,字符串模式)//如果输入字符串与模式匹配,则返回True,否则返回False。
IsMatch(“XYZ%”,“?Y%”)//应返回True
IsMatch(“YY?”,“?Y%”)//应返回True - 输入字符串中的最后一个字符需要单个字符,其中模式匹配Y之后的零个或多个字符(这意味着它包含单个字符)字符匹配)
IsMatch(“X123”,“?Y%”)//应返回False - 模式所需的输入字符串中缺少Y
IsMatch(“?Y%”,“?Y%”)//应返回True
IsMatch(“%”,“?Y%”)//应返回True - 输入字符串具有表示零个或多个字符的通配符%,并且还可以包含任何字符。在某种程度上,它本身就是一种模式,代表任何规模的任何东西。
我能够找到只讨论在非通配字符串上执行通配模式匹配的文章(例如:Regex)。我正在寻找关于算法的指针/想法,因为我很难想出一种可以做这种匹配的算法,因为我开始放下它。感谢您的意见。
答案 0 :(得分:2)
正如我在评论中写到的最常见的情况,你必须创建两个表达式的最小确定性有限自动机并比较两个自动机。说过你的问题可能有一个暴力/穷人的解决方案。
根据您的示例,您似乎有兴趣了解输入/模式中的一个是否匹配另一个生成的所有字符串。
IsMatch("XYZ%", "?Y%") // returns true because ?Y% matches a superset of strings matched by "XYZ%"
IsMatch("%", "?Y%") // returns true because "%" matches a superset of "?Y%"
您可以检查input
是否确实与pattern
生成的字符串子集匹配
基本思路是为input
生成代表性字符串列表,并使用您喜欢的正则表达式引擎将每个字符串与模式匹配。如果所有代表都匹配 - input
匹配pattern
的子集。 IsSubset
的此算法可以描述如下
let c = some character not in `pattern` (lexically speaking)
let searchString = replace all occurences of '?' in input with c
add searchString to setOfSearchStrings
foreach occurence of '%' in input
foreach str in setOfSearchStrings
replace str with two strings - {str with c in place of '%', str without the '%'}
foreach str in setOfSearchStrings
if str doesn't "regex" match with pattern
return false
return true
例如,如果输入为?X%YZ%且pattern
不包含字符A,则生成的列表将为
为axyz
AXYZA
AXAYZ
AXAYZA
很容易看出这个列表中的字符串数是2 ^ n,其中n是输入中'%'的数量。
也很容易交换参数的顺序,并相反地找出关系。所以实际上你的
IsMatch(input,pattern) = IsSubset(input,pattern) || IsSubset(pattern,input)