我正在尝试编写一些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中不允许空操作吗?如果没有,我该如何围绕日期标记序列添加单个注释?
谢谢。
最佳答案
允许没有动作的规则元素。需要省略包括箭头->
的完整部分(引号转义):
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的开发人员