如何更正正则表达式以找到确切的单词匹配而不区分大小写?

时间:2016-10-25 05:25:52

标签: java regex

我有一个私有方法,我正在测试并在下面提供,

private boolean containsExactDrugName(String testString, String drugName) {

    Matcher m = Pattern.compile("\\b(?:" + drugName + ")\\b|\\S+", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(testString);
    ArrayList<String> results = new ArrayList<>();

    while (m.find()) {
        results.add(m.group());
    }

    boolean found = results.contains(drugName);
    return found;
}

我在方法中提供了文本String和药物名称,并返回boolean。我需要它是案例insensitive,并且测试的最后assertion失败了。测试如下,

@Test
public void test_getRiskFactors_givenTextWith_Orlistat_Should_Not_Find_Medication() throws Exception {

    String drugName = "Orlistat";
    assertEquals("With Orlistat", true, containsExactDrugName("The patient is currently being treated with Orlistat", drugName));
    assertEquals("With Orlistattesee", false, containsExactDrugName("The patient is currently being treated with Orlistattesee", drugName));
    assertEquals("With abcOrlistat", false, containsExactDrugName("The patient is currently being treated with abcOrlistat", drugName));
    assertEquals("With orlistat", true, containsExactDrugName("The patient is currently being treated with orlistat", drugName));
}

在最后一个断言中,药物名称为小写orlistat,但仍需要与提供的参数Orlistat匹配。我使用了Pattern.CASE_INSENSITIVE,但它不起作用。如何正确编写代码?

2 个答案:

答案 0 :(得分:2)

问题主要不在于你的正则表达式,而是containsExactDrugName方法本身。您正在进行不区分大小写的匹配,以便在较大的字符串中找到drugName,但是您会在匹配字符串的结果列表中查找drugName完全匹配:

results.contains(drugName)

这个检查不仅是多余的(因为正则表达式已经完成了找到匹配项的工作),它正在积极地破坏你的功能,因为你再次检查一个精确的,区分大小写的匹配。简单地摆脱它:

private boolean containsExactDrugName(String testString, String drugName) {

    Matcher m = Pattern.compile("\\b(?:" + drugName + ")\\b", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(testString);
    List<String> results = new ArrayList<>();

    while (m.find()) {
        results.add(m.group());
    }

    return !results.isEmpty();
}

实际上,由于您没有跟踪找到drugName的次数,因此整个列表毫无意义,您可以将方法简化为:

private boolean containsExactDrugName(String testString, String drugName) {

    Matcher m = Pattern.compile("\\b(?:" + drugName + ")\\b", Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(testString);

    return m.find();
}

编辑 - 你的正则表达式也太宽容了。它匹配\\S+,这意味着任何一个或多个非空格字符的序列。我不确定你为什么要包括它,但这会导致你的正则表达式匹配不是drugName的东西。删除表达式的|\\S+部分。

答案 1 :(得分:1)

您需要(?i)在您希望不区分大小写的模式之前

更改你的正则表达式 来自

\\b(?:" + drugName + ")\\b|\\S+

到这个

(?i)\\b(" + drugName + ")\\b|\\S+