使用Apache OpenNLP查找空格分隔的名称

时间:2017-01-30 12:25:36

标签: java opennlp named-entity-recognition

我正在使用Apache Open NLP的 NER 。我已经成功培训了我的自定义数据。在使用 name finder 时,我根据空格分割给定的字符串并传递字符串数组,如下所示。

NameFinderME nameFinder = new NameFinderME(model);   
String []sentence = input.split(" "); //eg:- input = Give me list of test case in project X
Span nameSpans[] = nameFinder.find(sentence);

这里,当我使用split时, test case 作为单独的值给出,并且名字查找器永远不会检测到它。我怎么可能克服上述问题。有没有办法可以传递完整的字符串(不将其拆分成数组),这样,测试用例本身就会被视为一个整体?

1 个答案:

答案 0 :(得分:2)

您可以使用正则表达式来完成。尝试用这个替换第二行:

String []sentence = input.split("\\s(?<!(\\stest\\s(?=case\\s)))");

也许有更好的方法来编写表达式,但这适用于我,输出是:

Give
me
list
of
test case
in
project
X

编辑:如果您对此处的详细信息感兴趣,请点击此处:https://regex101.com/r/6HLBnL/1

编辑2:如果你有很多单词不能分开,我写了一个为你生成正则表达式的方法。这就是这种情况下的正则表达式应该是这样的(如果你不想在项目&#39中分离&#39;测试用例&#39; &#39; ; ):

\s(?<!(\stest\s(?=case\s))|(\sin\s(?=project\s)))

以下是一个简单的程序来演示它。在这个例子中,您只需在数组unseparated中放置不需要分隔的单词。

class NoSeparation {

private static String[][] unseparated = {{"test", "case"}, {"in", "project"}};

private static String getRegex() {
    String regex = "\\s(?<!";

    for (int i = 0; i < unseparated.length; i++)
        regex += "(\\s" + separated[i][0] + "\\s(?=" + separated[i][1] + "\\s))|";

    // Remove the last |
    regex = regex.substring(0, regex.length() - 1);

    return (regex + ")");
}

public static void main(String[] args) {
    String input = "Give me list of test case in project X";
    String []sentence = input.split(getRegex());

    for (String i: sentence)
        System.out.println(i);
}
}

编辑3:以下是处理超过2个字的字符串的非常脏的方法。它有效,但我很确定你能以更有效的方式做到这一点。它可以在短输入中正常工作,但是在更长的时间内它可能会很慢。

您必须将不应拆分的字放在二维数组中,如unseparated中所示。如果您因某些原因不想使用%%,也应该选择一个分隔符(例如,如果您的输入有可能包含它)。

class NoSeparation {

private static final String SEPARATOR = "%%";
private static String[][] unseparated = {{"of", "test", "case"}, {"in", "project"}};

private static String[] splitString(String in) {
    String[] splitted;

    for (int i = 0; i < unseparated.length; i++) {
        String toReplace = "";
        String replaceWith = "";
        for (int j = 0; j < unseparated[i].length; j++) {
            toReplace += unseparated[i][j] + ((j < unseparated[i].length - 1)? " " : "");
            replaceWith += unseparated[i][j] + ((j < unseparated[i].length - 1)? SEPARATOR : "");
        }

        in = in.replaceAll(toReplace, replaceWith);
    }

    splitted = in.split(" ");

    for (int i = 0; i < splitted.length; i++)
        splitted[i] = splitted[i].replaceAll(SEPARATOR, " ");

    return splitted;
}

public static void main(String[] args) {
    String input = "Give me list of test case in project X";
    // Uncomment this if there is a chance to have multiple spaces/tabs
    // input = input.replaceAll("[\\s\\t]+", " ");

    for (String str: splitString(input))
        System.out.println(str);
}
}