为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

茅侃侃 2022-06-15 17:35:25
我正在做一个项目,我需要在一段文本中搜索特定字符串。但是,我不需要完全匹配,更多的是 % 匹配。例如,这是我正在搜索的文本段落: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 infection2)Vasomotor rhinitis3)Allergic rhinitis due to pollen4)Other seasonal allergic rhinitis5)Allergic rhinitis due to food6)Allergic rhinitis due to animal (cat) (dog) hair and dander7)Other allergic rhinitis8)"Allergic rhinitis, unspecified"9)Chronic rhinitis10)Chronic nasopharyngitis我最初的方法是使用布尔值并包含:boolean found = med[x].toLowerCase().contains(condition[y].toLowerCase());但是,每次循环的结果都是负面的。我期望的结果是:1) False2) True3) True4) True5) True6) True7) True8) True9) True10) FalseJava 及其方法非常新。基本上,如果 A 中的任何单词与 B 中的任何单词匹配,则将其标记为 true。我怎么做?谢谢!
查看完整描述

3 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

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


像这样的东西应该工作:


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查找速度更快的 a 。


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);

您可能还想过滤掉停用词,例如to等and。您可以使用此处的列表并在检查空白字符串的过滤器之后添加一个额外的过滤器,以检查该字符串是否不是停用词。


查看完整回答
反对 回复 2022-06-15
?
人到中年有点甜

TA贡献1895条经验 获得超7个赞

这将为您提供“粗略”的匹配百分比。

以下是它的工作原理:

  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;

希望这可以帮助。


查看完整回答
反对 回复 2022-06-15
?
潇湘沐

TA贡献1816条经验 获得超6个赞

如果你用可搜索的词构建一个列表,这会容易得多。假设您的段落存储为字符串:


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");

    }

}


查看完整回答
反对 回复 2022-06-15
  • 3 回答
  • 0 关注
  • 188 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信