【问题标题】:Regex pattern classification for Java?Java的正则表达式模式分类?
【发布时间】:2011-05-20 06:26:38
【问题描述】:

比如我要分类c*t => CLASS1,而d*g => CLASS2:

Pattern CXT = Pattern.compile("^c.*t$");
Pattern DXG = Pattern.compile("^d.*g$");

public int classify(String in) {
    if (CXT.matches(in)) return CLASS1;
    if (DXG.matches(in)) return CLASS2;
    return -1;
}

如果有很多模式模式,效率非常低。

假设所有模式都是正交的,很容易看到一个 DFA 中的单次通过就足够了。那么,是否存在可以将所有模式组合在一起的正则表达式处理器?

【问题讨论】:

  • 这和Java有什么关系?
  • 如何不丢失信息? (即 C 和 D 是不同的回报)
  • 模式的第一个字母和你返回的字母有关系吗?
  • 好吧,我想知道一个开源Java库,它将多个模式编译成一个,并告诉输入字符串被哪个模式接受。
  • @Seth:我已经更新了问题,谢谢。

标签: java regex recommendation-engine


【解决方案1】:

你应该看看dk.brics.automaton 包,它不是你要找的,但它是一个非常快速的状态机实现与BSD许可证 .

因此,您可以构建自动机,它比正则表达式更快地为您进行分类。

【讨论】:

  • 我已经检查了api,是的。
  • 有一个BasicOperations.union() 可以帮助您组合以前构建的自动机。
【解决方案2】:
/^((c.*t)|(d.*g))$/

然后您查看找到了哪个匹配项。如果您看到 $2,则返回 CLASS1。如果看到 $3,则返回 CLASS2 等。

【讨论】:

    【解决方案3】:

    你可以做例如(未测试):

    Pattern pat = Pattern.compile("^((c.*t)|(d.*g))$");
    
    
    public int classify(String in) {
        Matcher m = pat.matcher(in);
        if (m.matches()) {
            if ( m.group(2) != null ) {
                 return C;
            }
            else if ( m.group(3) != null ) {
             return D;
            }
        }
        return -1;
    }
    

    但我不确定这会比您当前的代码更有效。无论哪种方式,您都必须比较所有可能模式的输入,无论是显式执行还是将其构建到正则表达式中

    【讨论】:

    • 您需要在选项周围加上括号,因为 ^ 适用于 cxt 而 $ 适用于 dxg。
    • Pattern 实现中,'|' 似乎被编译为Pattern.Branch,但是,它只是遍历所有分支,而不是在 DFA 图中合并或合并它们。
    • 我不相信这个问题有一个 DFA 图,它与 N 个单独的子 DFA 根本不同,其中 DFA 可以区分 cat 和 dot,并且每种语言都有不同的停止状态匹配。除了开始状态和 ^ 匹配之外,没有其他共同的状态。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    • 1970-01-01
    • 2010-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多