2013-04-16 150 views
10

我希望从包含数字的字符串生成正则表达式,然后将其用作模式来搜索相似的字符串。例如:从字符串生成正则表达式

String s = "Page 3 of 23" 

如果我代替所有的数字由\d

StringBuilder sb = new StringBuilder(); 
    for (int i = 0; i < s.length(); i++) { 
    char c = s.charAt(i); 
    if (Character.isDigit(c)) { 
     sb.append("\\d"); // backslash d 
    } else { 
     sb.append(c); 
     } 
    } 

    Pattern numberPattern = Pattern.compile(sb.toString()); 

// Pattern numberPattern = Pattern.compile("Page \d of \d\d"); 

我可以使用该匹配的相似字符串(例如"Page 7 of 47")。我的问题是,如果我天真地这样做,一些元字符如(){}-等不会被转义。有没有一个图书馆可以做到这一点,或者一个正规表达式的详尽字符集,我必须也不能逃避? (我可以尝试从Javadocs中提取它们,但是担心错过了某些内容)。

或者是有一个库已经这样做了(我现阶段不想使用完整的自然语言处理解决方案)。

注意:@ dasblinkenlight的编辑答案现在适用于我!

+0

下面是对哪些字符问题的回答,我不知道任何库可以生成正则表达式:http://stackoverflow.com/questions/399078/what-special-characters-must-be-escaped-in -regular-expressions –

+0

@Evan谢谢。我只对Java感兴趣,因此看起来像一个有用的资源。 –

回答

10

Java的正则表达式库提供此功能:

String s = Pattern.quote(orig); 

的“引用”的字符串将其所有的元字符转义。首先,跳过你的字符串,然后遍历它,并用\d替换数字来进行正则表达式。由于正则表达式库使用\Q\E进行引用,因此您需要将您的部分正则表达式用\E\Q的反引号括起来。

我会改变你的实现中的一件事是替换算法:而不是逐个字符替换,我会替换组中的数字。这可以让从Page 3 of 23产生的表达式匹配字符串,如Page 13 of 23Page 6 of 8

String p = Pattern.quote(orig).replaceAll("\\d+", "\\\\E\\\\d+\\\\Q"); 

produce"\QPage \E\d+\Q of \E\d+\Q\E"无论什么页码和计数在那里原本。输出只需要一个,而不是\d中的两个斜线,因为结果直接馈送到正则表达式引擎,绕过Java编译器。

+0

很酷,我不知道这个方法。 – toniedzwiedz

+0

@dasblinkenlight太好了!同意我可能会寻找重复的数字,但也有启发式值具有精确的数字计数。我可以使用这两种方法。 –

+0

@ peter.murray.rust查看最后一次编辑:在输出中制作两个斜线所需的斜杠数量非常荒谬 - 编译器时间为2,正则表达式库时间为2,总共8个斜杠。 – dasblinkenlight