【问题标题】:How to check if a word is present in a sentence using Java? [duplicate]如何使用Java检查句子中是否存在单词? [复制]
【发布时间】:2014-04-30 04:08:15
【问题描述】:

我是编程新手,并且正在研究一个函数以在句子中出现单词时返回 true。我尝试了indexOf() 方法,但后来我也遇到了这种方法的某个问题:

假设我的句子是I am a, Java Programmer.

如果我们使用indexOf() 方法查找单词ram,那么它将返回true,因为ram 存在于Programmer 中,而正确的输出应该是false,因为ram 不存在以单词的形式呈现,但以模式的形式呈现。

我该如何解决这个问题?我现在使用的代码是:

boolean isPresent(String word, String sentence)
{
    if(sentence.indexOf(word) >= 0)
        return true;
    else
        return false;
}

注意: ram 这个词只是一个例子,说明了我目前的方法存在的问题之一。并不是我必须一直使用 ram。这个词可以是a 之类的任何东西,在上面的句子中后跟一个逗号。

更新:感谢大家提供他们的 cmets 和解决方案。我选择了一个作为接受的答案(如果允许,我会选择更多:-)),但很多都是有帮助的。

【问题讨论】:

  • 您可以使用 string.split 方法,然后检查结果数组是否包含您的单词。
  • 顺便说一句,您可以像这样简化该函数的定义:return sentence.indexOf(word) >= 0; - sentence.indexOf(word) >= 0truefalse,因此根据情况,这意味着 return true;return false;.
  • 这个问题清晰而完整,但我可以在 Stackoverflow 和许多其他地方多次找到这个问题的答案。
  • @AbuSulaiman 在这种情况下,您应该投票关闭这个问题作为重复,而不是仅仅发表评论。

标签: java pattern-matching


【解决方案1】:

尝试正则表达式

boolean contains = s.matches(".*\\bram\\b.*");

\b 表示单词边界

【讨论】:

  • +1 用于使用单词边界(你可以扔掉.*
  • IIRC,整个s必须匹配Java中给定的正则表达式,所以.*必须保留。
  • 使用空格标记器来解决这个问题在技术上不是更正确吗?
  • @Fuser97381 在没有额外的预处理/后处理的情况下搜索a(由于逗号)
  • @SalmanA 在java中,你必须保留".*"任一端
【解决方案2】:

既然要搜索一个词,有以下三种情况:

  1. 句子开头的单词表示开头没有空格,但结尾有空格。
  2. 单词在两端的句子空间之间。
  3. 单词末尾只有空格。

要涵盖所有三种情况,一种可能的解决方案是:

String str = "I am a JAVA programmer";
String[] splited = str.split("\\b+"); //split on word boundries
Arrays.asList(splited).contains("ram"); //search array for word

Here is working Demo

【讨论】:

  • 如果 OP 想要搜索不区分大小写的单词怎么办
  • 如果 OP 想要我会推荐他stackoverflow.com/a/15269846/821057
  • 还有 OP 示例中的逗号(如果他们正在搜索 a)?
  • 按单词边界分割不会也返回单词间序列吗?
【解决方案3】:

问题:

你如何定义一个词?

可能的答案:

由其他字符分隔的一堆字符。第二组字符由您选择的字符定义。假设您选择这些为. ,?;。所以如果你用这些字符(称为delimiters)分割输入字符串,你会得到一堆字符串,它们是words。现在要查找输入是否包含该单词,请遍历这些字符串以检查它们是否与您的查询匹配。

代码:

boolean isPresent(String query, String s) {    
    String [] deli = s.split("[.\\s,?;]+");

    for(int i=0;i<deli.length;i++)
        if(query.equals(deli[i]))
            return true;

    return false;    
}

tl;博士:

如果您希望将单词定义为由字母、数字和下划线组成的任何内容,则可以使用正则表达式:\W+

String [] deli = s.split("\\W+");

如果您想了解有关 Java 正则表达式的更多信息,请考虑阅读 this article

【讨论】:

  • 很好的答案,但请注意 split 接受正则表达式。所以你可以只在空白处分割,或者不是 alpha,或者其他什么。你也可以用 equalsIgnoreCase 来匹配大写的单词。
  • 正如@TimB 提到的,String.split 采用正则表达式字符串。这意味着两件事。首先,你不能向它提供这样的字符列表(它会尝试使用 整个字符串 作为匹配 single boundary 的正则表达式模式),尽管你可以使用正则表达式字符类 ("[. ,?;]")。其次,必须对任何正则表达式元字符进行转义 - 您对 . 的使用将匹配任何单个字符,而 ? 将使 , 成为可选的。
  • 虽然这个答案很好,因为它有助于让读者思考需要发生的事情,但重要的是要注意\\b 是一个可用的元字符来指示单词边界,这正是 OP 正在寻找的东西。不过,请务必区分 \\b(单词边界)和 \b(退格)!
  • 您不应在字符类中使用或 (|)。这不是字符类的工作方式。
  • 按单词边界分割不会也返回单词间序列吗?我期待s.split("\\W+")(虽然这可能会产生空字符串,但不确定这些方法在java中是如何工作的)
【解决方案4】:

看看String.matches() 方法。如果你正确地构造正则表达式,它应该能够做你想做的事情。 Java 教程是学习正则表达式的好地方:http://docs.oracle.com/javase/tutorial/essential/regex/

【讨论】:

  • 这不适用于整个句子。 String.matches() 仅在整个字符串匹配时才返回 true
  • 所以你可以做一些像"*\\s+" + word + "\\s+*" 这样的正则表达式,对吧?这应该适用于句子......(可能不是正确的语法,但这是一般的想法)
  • 是的。那会(有点)工作。我还建议在 Java 文档中查找 PatternMatcher 对象。两者都是用于正则表达式字符串匹配的类,前者用于模式生成,后者用于搜索。 (显然)
【解决方案5】:

如果你想匹配一个句子中的单词,即使有标点符号,你需要一个这样的正则表达式:

  static boolean matchesWord(String toMatch, String matchIn) {
     return Pattern.matches(".*([^A-Za-z]|^)"+toMatch+"([^A-Za-z]|$).*", matchIn);
  }

(您可以使用 \W,但这不算下划线作为标点符号。)

只是将空格连接到开头和结尾不会匹配,例如字符串“我是 Java 程序员”中的单词“程序员”,因为结尾没有空格。它也不会直接匹配标点符号之前或之后的单词。

【讨论】:

    【解决方案6】:
    String s="I am a JAVA programmer";
        String s1="JAVA";
        String []p=s.split("\\s*(=>|,|\\s)\\s*");
            for(int i=0;i<p.length;i++)
            {
                if(s1.equals(p[i]))
                {
                    System.out.println(p[i]);
                }
    
            }
    

    【讨论】:

      【解决方案7】:

      一个更简单的方法是:如果你认为一个词类似于

      “我的电脑有 ram 内存”(在空格之间)

      你可以在你正在搜索的单词之前和之后连接到你的 indexOf 函数空间,就像这样

      if (sentence.indexOf(" "+ word +" ") >= 0) {

      【讨论】:

      • 嗨@jhonis.souza,欢迎来到 StackOverflow。您可能需要考虑要找到的单词是句子中的第一个或最后一个的情况 - 例如,您将如何处理有人试图在句子中找到单词 Hello 的情况 Hello world,没有前导空格?
      • 是的,你是对的!我在这里尝试使用的方式并不是更自信,正确的方式是使用拆分或正则表达式,我只是试图展示更简单的解决方法或其他思考问题的方式,哈哈。谢谢指正。
      • 更改为(" " + sentence + " ").indexOf..
      【解决方案8】:

      假设每个单词都用空格分隔,这将起作用。为了清楚起见,我添加了主要功能。如果单词不存在,find_str 返回 -1。否则,它返回单词相对于其他单词的位置。这里会返回 2,表示第二个单词是 'am'。

      import java.util.*;
      public class HelloWorld{
      
          public static void main(String []args){
              String str="I am a Java Programmer";
              String str1="am";
              int x=find_str(str,str1);
              System.out.println(x);
      
          }
      
          public static int find_str(String main,String search) {
      
              int i; 
              int found=-1;
      
              String[] s=main.split(" ");
              for(i=0;i<s.length;i++)
              {
                  if(search.equals(s[i]))
                  found=i+1;
              }
              return found;
          }
      }
      

      【讨论】:

      • 如果str1之后有标点符号,这将不起作用。
      • 你可能是对的。我什至没有想到这一点。让我看看能不能找到解决方法。
      【解决方案9】:

      这是一个相当笨拙的解决方法,但应该会获得正确的结果。在字符串中找到您要查找的子字符串,并在您的子字符串之前和之后找到字符。使用它们的 ascii 值(int)substring.charAt(x);检查它们以查看它们是否是字母。如果它们都不是字母,或者都超出了字符串的范围,那么您就知道您找到了一个单词。否则,您知道它只是单词的一部分。

      逻辑会很长——这就是为什么我没有为你编写代码的原因,但是试一试,如果你需要澄清,请告诉我。

      【讨论】:

      • -1 推荐使用 ASCII 值。我们已经过了可以接受代码不支持 Unicode 的时期。
      • 我为此使用了 ASCII,因为当您将 char 转换为 int 时,默认返回值是 ASCII 值。这是 java 所固有的。
      【解决方案10】:

      喂。您可以将句子拆分为数组,然后放入 List。之后,您可以使用 contains 方法检查您的单词是否存在。请尝试此代码..

      import java.util.ArrayList;
      import java.util.Arrays;
      
      
       public class karthitest {
        public static void main(String[] args) {
          String sentence = "I am Karthick";
          String word = "I";
      
          if(isWordExist(sentence, word)){
          System.out.println("Word is exist");
          }
      }
      
      public static boolean isWordExist(String sentence, String word){
          boolean ans = Boolean.FALSE;        
          ArrayList<String> wordList = null;
      
          try {
      
              if(sentence != null && word != null){
                  wordList = new ArrayList<String>(Arrays.asList(sentence.split("[^a-zA-z]+")));              
                  if(wordList.contains(word)){
                      ans = Boolean.TRUE;
                  }
              }
          } catch (Exception e) {
              e.printStackTrace();
              // TODO: handle exception
          }
          return ans;
      }
      
      }
      

      【讨论】:

      • I am Karthick, you are not 的工作原理 - 搜索 Karthick
      • 对不起.. 我没听懂。
      • 根据您的代码,您将获得以下令牌IamKarthick,youarenot
      • 我已经测试了我句子中的所有三个单词并得到了正确答案
      • 所以把句子改成I am Karthick, you are not再试一次。
      【解决方案11】:

      试试这个解决方案

          int index = sent.indexOf(find);
          if (index != -1) {
              if (index == 0) {
                  System.out.println("true");
              }
              else if (index + find.length() == sent.length())
              {
                  System.out.println("true");
              }
              else if (sent.charAt(index - 1) == ' ' && sent.charAt(find.length() + index) == ' ') {
                  System.out.println("true");
              } else {
                  System.out.println("false");
              }
      
          } else {
              System.out.println("false");
          }
      

      如果您想要的不仅仅是原始问题,那么您应该检查空格是否不在 0-9 和 a-Z 之间,这应该涵盖逗号等任何字符。

      【讨论】:

      • 如果句子开头的单词比结尾处没有空格怎么办。
      • 如果单词将是句子中的第一个单词,这将不起作用
      • 喂。假设我的词是“我”,那么你的答案是什么?
      • 如果我想在上面的句子I am a, Java Programmer 中搜索a 怎么办。根据您的代码,它将返回 False,因为在 index + 1 之后您会看到一个逗号,不是吗?
      • 当然,如果您想更新您的问题以包含此内容,那么我将简单地添加代码以检查 index + 1 不在 0-9 和 a-Z 之间。
      【解决方案12】:

      使用包含方法

      boolean isPresent(String word, String sentence)
      {
      return sentence.contains(word);   
      }
      

      编辑: 如果你想搜索一个特定的词,那么你可以在字符串之前和之后添加空格
      单词 = " " + 单词 + " ";

      【讨论】:

      • 我没有投反对票,但这个答案是错误的。
      • String.contains() 只返回参数是否在调用它的字符串中显示为子字符串;因此,它不适用于发帖者的情况,因为他希望仅当参数显示为独立单词而不是可能在另一个单词中的子字符串时,使用任何方法返回 true。
      • 可能是因为它未能通过问题中的示例:isPresent("ram", "I am a, Java Programmer.") 是真的,但应该是假的。
      • 我没有投反对票,但这个建议在逻辑上等同于 OP 的现有代码。
      猜你喜欢
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 1970-01-01
      • 1970-01-01
      • 2018-04-21
      • 2014-11-27
      • 1970-01-01
      相关资源
      最近更新 更多