以编程方式查找正则表达式字符串?

时间:2017-09-14 05:52:10

标签: regex string algorithm performance time-complexity

给定正则表达式,是否可以找到以编程方式匹配该表达式的字符串?如果是这样,请提及一个算法,假设存在一个字符串。

奖金问题:如果能够,请提供该算法的性能/复杂性。

PS:注意我不是这样问:Programmatically derive a regular expression from a string。我更有可能问保留问题。

3 个答案:

答案 0 :(得分:3)

Generex是一个用于从正则表达式生成String的Java库。

检查出来:https://github.com/mifmif/Generex

以下是演示库使用情况的示例Java代码:

Generex generex = new Generex("[0-3]([a-c]|[e-g]{1,2})");

// Generate random String
String randomStr = generex.random();
System.out.println(randomStr);// a random value from the previous String list

// generate the second String in lexicographical order that match the given Regex.
String secondString = generex.getMatchedString(2);
System.out.println(secondString);// it print '0b'

// Generate all String that matches the given Regex.
List<String> matchedStrs = generex.getAllMatchedStrings();

// Using Generex iterator
Iterator iterator = generex.iterator();
while (iterator.hasNext()) {
    System.out.print(iterator.next() + " ");
}
// it prints:
// 0a 0b 0c 0e 0ee 0ef 0eg 0f 0fe 0ff 0fg 0g 0ge 0gf 0gg
// 1a 1b 1c 1e 1ee 1ef 1eg 1f 1fe 1ff 1fg 1g 1ge 1gf 1gg
// 2a 2b 2c 2e 2ee 2ef 2eg 2f 2fe 2ff 2fg 2g 2ge 2gf 2gg
// 3a 3b 3c 3e 3ee 3ef 3eg 3f 3fe 3ff 3fg 3g 3ge 3gf 3gg

另一个:https://code.google.com/archive/p/xeger/

以下是演示库使用情况的示例Java代码:

String regex = "[ab]{4,6}c"; 
Xeger generator = new Xeger(regex); 
String result = generator.generate(); 
assert result.matches(regex);

答案 1 :(得分:1)

假设你定义了这样的正则表达式:

R :=
   <literal string>
   (RR)    -- concatenation
   (R*)    -- kleene star
   (R|R)   -- choice

然后你可以定义一个递归函数S(r),它找到一个匹配的字符串:

S(<literal string>) = <literal string>
S(rs) = S(r) + S(s)
S(r*) = ""
S(r|s) = S(r)

例如:S(a*(b|c)) = S(a*) + S(b|c) = "" + S(b) = "" + "b" = "b"

如果你有一个更复杂的正则表达式概念,你可以用基本原语重写它,然后应用上面的。例如,R+ = RR*[abc] = (a|b|c)

请注意,如果你有一个经解析的正则表达式(所以你知道它的语法树),那么上面的算法最多只需要正则表达式大小的线性(假设你要小心)有效地执行字符串连接)。

答案 2 :(得分:1)

要在字符串中找到符合该条件的给定表达式,我尝试过以下算法。

i) Create the array for all strings available in given source.

ii) Create a function with parameters for array, expression and initial index count.

iii) Call function recursively and increase the index with every move, until we match string has not found.

iv) Return/break the function if String with desired expression is found.

以下是相同的java代码:

public class ExpressionAlgo {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        String data = "A quantifier defines how often an element can occur. The symbols ?, *, + and {} define the quantity of the regular expressions";
        regCheck(data.split(" "), "sym", 0); 
    }

    public static void regCheck(String[] ar, String expresion, int i) {
               if(ar[i].contains(expresion)){
                   System.out.println(ar[i]);
                   return;
               }

               if(i<ar.length-1){
                   i=i+1;
                   regCheck(ar, expresion, i);
               }
    }
}

据我计算,这段代码的复杂性是N ^ 3,因为我使用了split,contains方法和递归调用regCheck方法。