空行动导致“找不到可行的替代方案”

时间:2017-04-06 19:07:03

标签: java uima ruta

我正在尝试编写一些Ruta规则,这些规则在日期周围创建时间注释。下面的测试显示了我是如何尝试的。

@Test
public void test__Ruta__AnnotateDate() throws UIMAException, IOException, URISyntaxException {
    final class RulesRunner {
        public void applyRules(JCas cas, String[] rules) throws AnalysisEngineProcessException, InvalidXMLException, ResourceInitializationException, ResourceConfigurationException, IOException, URISyntaxException {
            for (String aRule: rules) {
                Ruta.apply(cas.getCas(), aRule);
            }
        }
    }

    RulesRunner runner = new RulesRunner();

    JCas cas = JCasFactory.createJCas();
    cas.setDocumentText("Today's date is 2017-04-06.");

    // Tokenize the string
    String[] rules = new String[] {
            "ANY{REGEXP(\"[a-zA-Z0-9]+\") -> Token};",
            "ANY{REGEXP(\"[^ a-zA-Z0-9]+\") -> Token};"
    };
    runner.applyRules(cas, rules);

    rules = new String[] {
        // Does not crash, but gives:
        //   Got Time=2017-04-06
        //   Got Time=-
        //   Got Time=04
        //   Got Time=-
        //   Got Time=06
        //  
        "Token{REGEXP(\"[0-9]{4}\") -> MARK(Time, 1, 5)} Token{REGEXP(\"-\") -> Time} Token{REGEXP(\"[0-9]{2}\") -> Time} Token{REGEXP(\"-\") -> Time} Token{REGEXP(\"[0-9]{2}\") -> Time};"

        // Crashes with exception
        //
        //   org.apache.uima.ruta.extensions.RutaParseRuntimeException: 
        //     Error in Ruta7969125931572676994,  line 1, "}": found no viable alternative
        //
        // "Token{REGEXP(\"[0-9]{4}\") -> MARK(Time, 1, 5)} Token{REGEXP(\"-\") -> } Token{REGEXP(\"[0-9]{2}\") -> } Token{REGEXP(\"-\") -> } Token{REGEXP(\"[0-9]{2}\") -> };"

    };
    runner.applyRules(cas, rules);

    for (Time aTime: JCasUtil.select(cas, Time.class)) {
        System.out.println("Got Time="+aTime.getCoveredText());
    }
}

测试首先注释标记,然后尝试在形式['YYYY',' - ','MM',' - ','DD']的任何标记序列周围放置时间注释。

我尝试了两条规则来做到这一点。第一条规则是“一种工作”,即时间注释确实围绕着整个序列序列。但它也在日期的每个成分周围添加了时间注释(YYYY部分除外)。

在第二条规则中,我尝试对其他标记的匹配结果使用空操作,但这会导致“找不到可行的替代”异常。 Ruta不允许空行动吗?如果没有,我将如何在日期标记序列周围添加单个注释?

THX。

1 个答案:

答案 0 :(得分:0)

允许不带操作的规则元素。包含箭头->的完整部分需要省略(引用转义):

Token{REGEXP(\"[0-9]{4}\") -> MARK(Time, 1, 5)} Token{REGEXP(\"-\")} Token{REGEXP(\"[0-9]{2}\")} Token{REGEXP(\"-\")} Token{REGEXP(\"[0-9]{2}\")};

在第一个规则中,每个令牌的附加Time注释由规则元素处的操作创建。如果你删除它们,你就会像你那样结束第二条规则。

我建议稍微优化您的规则,例如,使用一些-PARTOF(Time)以避免重叠注释。

我会写一些规则(没有转义引号):

(NUM{-PARTOF(Time),REGEXP(".{4}")}
 SPECIAL.ct=="-"
 NUM{REGEXP(".{2}")}
 SPECIAL.ct=="-"
 NUM{REGEXP(".{2}")}
){-> Time};

如果您在多个规则中使用这些规则元素,我会重构它以分隔注释,例如Dash,Num4和Num2。

免责声明:我是UIMA Ruta的开发者