Java搜索字符串内容以进行部分匹配

问题描述 投票:3回答:3

我正在开发一个项目,我需要在其中搜索特定字符串的文本段落。但是,我不需要完全匹配,更多的是匹配。

例如,这是我正在搜索的文本段落:

Fluticasone Propionate Nasal Spray, USP 50 mcg per spray is a 
corticosteroid indicated for the management of the nasal symptoms of 
perennial nonallergic rhinitis in adult and pediatric patients aged 4 years 
and older."

然后我正在搜索以下行中的任何单词是否与段落匹配:

1)Unspecified acute lower respiratory infection
2)Vasomotor rhinitis
3)Allergic rhinitis due to pollen
4)Other seasonal allergic rhinitis
5)Allergic rhinitis due to food
6)Allergic rhinitis due to animal (cat) (dog) hair and dander
7)Other allergic rhinitis
8)"Allergic rhinitis, unspecified"
9)Chronic rhinitis
10)Chronic nasopharyngitis

我最初的方法是使用布尔值并包含:

boolean found = med[x].toLowerCase().contains(condition[y].toLowerCase());

但是,每个循环的结果都是负数。

我期望的结果是:

1) False
2) True
3) True
4) True
5) True
6) True
7) True
8) True
9) True
10) False

Java及其方法的新手。基本上,如果A中的任何单词与B中的任何单词匹配,则将其标记为true。我怎么做?

谢谢!

java string string-matching
3个回答
1
投票

您必须先对其中一个字符串进行标记。你现在正在做的是试图匹配整条线。

这样的事情应该有效:

String text = med[x].toLowerCase();
boolean found = 
  Arrays.stream(condition[y].split(" "))      
      .map(String::toLowerCase)
      .map(s -> s.replaceAll("\\W", "")
      .filter(s -> !s.isEmpty())
      .anyMatch(text::contains);

我添加了删除标点字符和任何空字符串,以便我们不会对这些字符进行错误匹配。 (\\W实际上删除了不在[A-Za-z_0-9]中的字符,但您可以将其更改为您喜欢的任何字符)。

如果你需要这个有效率,因为你有很多文本,你可能想转过它并使用一个更快查找的Set

private Stream<String> tokenize(String s) {
   return Arrays.stream(s.split(" "))
                .map(String::toLowerCase)
                .map(s -> s.replaceAll("\\W", "")
                .filter(s -> !s.isEmpty());                   
}

Set<String> words =  tokenize(med[x]).collect(Collectors.toSet());

boolean found = tokenize(condition[y]).anyMatch(words::contains);

您可能还想过滤掉停止词,例如toand等。您可以使用列表here并在检查空字符串之后添加额外的过滤器,以检查字符串是否不是停用词。


0
投票

如果您使用可搜索的单词构建列表,这将更容易。假设您的段落存储为字符串:

ArrayList<String> dictionary = new ArrayList<>();
dictionary.add("acute lower respiratory infection");
dictionary.add("rhinitis");
for(int i =0; i<dictionary.size(); i++){
    if(paragraph.contains(dictionary.get(i))){
        System.out.println(i + "True");
    }
    else{
         System.out.println(i +"False");
    }
}

0
投票

这将为您提供“原始”匹配百分比。

以下是它的工作原理:

  1. 将文本拆分为搜索,将搜索词拆分为一组单词。这是通过使用正则表达式拆分来完成的。每个单词都转换为大写并添加到一个集合中。
  2. 计算搜索词中出现的单词数量。
  3. 计算文本中显示的搜索词中的单词百分比。

您可能希望通过删除诸如“a”,“the”等常用词来增强此功能。

    import java.util.Arrays;
    import java.util.Set;
    import java.util.stream.Collectors;

    public class CrudeTextMatchThingy {

        public static void main(String[] args) {
            String searchText = "Fluticasone Propionate Nasal Spray, USP 50 mcg per spray is a \n" +
                    "corticosteroid indicated for the management of the nasal symptoms of \n" +
                    "perennial nonallergic rhinitis in adult and pediatric patients aged 4 years \n" +
                    "and older.";

            String[] searchTerms = {
                "Unspecified acute lower respiratory infection",
                "Vasomotor rhinitis",
                "Allergic rhinitis due to pollen",
                "Other seasonal allergic rhinitis",
                "Allergic rhinitis due to food",
                "Allergic rhinitis due to animal (cat) (dog) hair and dander",
                "Other allergic rhinitis",
                "Allergic rhinitis, unspecified",
                "Chronic rhinitis",
                "Chronic nasopharyngitis"
            };

            Arrays.stream(searchTerms).forEach(searchTerm -> {
                double matchPercent = findMatch(searchText, searchTerm);
                System.out.println(matchPercent + "% - " + searchTerm);
            });
        }

        private static double findMatch(String searchText, String searchTerm) {
            Set<String> wordsInSearchText = getWords(searchText);
            Set<String> wordsInSearchTerm = getWords(searchTerm);

            double wordsInSearchTermThatAreFound = wordsInSearchTerm.stream()
                    .filter(s -> wordsInSearchText.contains(s))
                    .count();

            return (wordsInSearchTermThatAreFound / wordsInSearchTerm.size()) * 100.0;
        }

        private static Set<String> getWords(String term) {
            return Arrays.stream(term.split("\\b"))
                    .map(String::trim)
                    .map(String::toUpperCase)
                    .filter(s -> s.matches("[A-Z0-9]+"))
                    .collect(Collectors.toSet());
        }
    }

输出:

    0.0% - Unspecified acute lower respiratory infection
    50.0% - Vasomotor rhinitis
    20.0% - Allergic rhinitis due to pollen
    25.0% - Other seasonal allergic rhinitis
    20.0% - Allergic rhinitis due to food
    20.0% - Allergic rhinitis due to animal (cat) (dog) hair and dander
    33.33333333333333% - Other allergic rhinitis
    33.33333333333333% - Allergic rhinitis, unspecified
    50.0% - Chronic rhinitis
    0.0% - Chronic nasopharyngitis

如果你不想要一个百分比,但是真或假,你可以做...,

    boolean matches = findMatch(searchText, searchTerm) > 0.0;

希望这可以帮助。

© www.soinside.com 2019 - 2024. All rights reserved.