更改字符串以匹配正则表达式

时间:2010-09-12 10:47:31

标签: regex

是否有可能(或者为什么不可能)将输入字符串转换为匹配最少Levenshtein距离的正则表达式的字符串?

即。如果1234是字符串并且^([0-9] {6})$是正则表达式,我需要输出类似123412(输出字符串匹配正则表达式并且与原始字符串相距2个距离,可能还有其他字符串但是第一个结果会做)

怎么做? (没有蛮力..)

编辑:

在其他可能性中,我可以只获得Levenshtein距离吗? (没有匹配的字符串...)

或者除了布尔(匹配或不匹配)之外的其他信息可以正则表达式吗?

1 个答案:

答案 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