是否有可能(或者为什么不可能)将输入字符串转换为匹配最少Levenshtein距离的正则表达式的字符串?
即。如果1234是字符串并且^([0-9] {6})$是正则表达式,我需要输出类似123412(输出字符串匹配正则表达式并且与原始字符串相距2个距离,可能还有其他字符串但是第一个结果会做)
怎么做? (没有蛮力..)
编辑:
在其他可能性中,我可以只获得Levenshtein距离吗? (没有匹配的字符串...)
或者除了布尔(匹配或不匹配)之外的其他信息可以正则表达式吗?
答案 0 :(得分:4)
如果您了解finite automaton,您可以构建一个代表您的正则表达式(有库可以这样做)。然后用你的字符串(1234
)运行它,你最终会处于某种状态。在此状态下,您执行breath-first search直到达到接受状态。在搜索时,您可以跟踪您跑过的过渡(角色)。并且角色将为您提供最短(或其中一个)字符串,使您的正则表达式合格。
添加链接:您可以查看http://www.brics.dk/automaton/这是在奥胡斯大学实施的自动机库(BSD许可证)
更新:我已经使用上面的自动机实现构建了您所寻求的内容。首先,ExtendedOperations类与其他自动机类位于同一个包中,因为我需要访问某些方法。
package dk.brics.automaton;
public class ExtendedOperations {
//Taken from Automaton.run and modified to just return state instead of accept (bool)
static State endState(String s, Automaton a)
{
if (!a.deterministic) a.determinize();
State p = a.initial;
for (int i = 0; i < s.length(); i++) {
p = p.step(s.charAt(i));
if (q == null) return null;
}
return p;
}
public static String getShortestCompletion(Automaton a, String partlyInput)
{
State e = endState(partlyInput, a);
if (e == null) return null;
return BasicOperations.getShortestExample(e, true);
}
}
其次,一点测试样本:
package subsetautomaton;
import dk.brics.automaton.*;
public class Main {
public static void main(String[] args) {
RegExp re = new RegExp("[a-zA-Z0-9._%+-]+\\@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}");
Automaton a = re.toAutomaton();
System.out.println(ExtendedOperations.getShortestCompletion(a, "a"));
}
}
该示例是一个天真的电子邮件地址注册。进出口。请注意,^
隐含在reg中。进出口。和$
一样。其次,@
使用\
进行转义,因为在此实现中它意味着“任何字符串”。
上面示例的结果是:@-.AA