【问题标题】:Check if string contains word (not substring!)检查字符串是否包含单词(不是子字符串!)
【发布时间】:2016-04-22 12:05:06
【问题描述】:

有没有办法检查子字符串是否包含整个 WORD,而不是子字符串。

设想以下场景:

public class Test {
    public static void main(String[] args) {
        String[] text = {"this is a", "banana"};
        String search = "a";

        int counter = 0;
        for(int i = 0; i < text.length; i++) {
            if(text[i].toLowerCase().contains(search)) {
                counter++;
            }
        }

        System.out.println("Counter was " + counter);
    }
}

计算结果为

Counter was 2

这不是我要找的,因为数组中只有一个单词“a”的实例。

我的阅读方式如下:

if-test 在 text[0] 中找到一个 'a','a' 对应于“this is [a]”。但是,它也会在“banana”中找到出现的“a”,从而增加计数器。

如何解决这个问题,只包含单词“a”,而不包含包含 a 的子字符串?

谢谢!

【问题讨论】:

    标签: java substring word


    【解决方案1】:

    您可以使用正则表达式,使用 Pattern.quote 转义任何特殊字符。

    String regex = ".*\\b" + Pattern.quote(search) + "\\b.*"; // \b is a word boundary
    
    int counter = 0;
    for(int i = 0; i < text.length; i++) {
        if(text[i].toLowerCase().matches(regex)) {
            counter++;
        }
    }
    

    请注意,这也会在"this is a; pause""Looking for an a?" 中找到"a",其中a 后面没有空格。

    【讨论】:

    • if(text[i].toLowerCase().matches(regex)) {
    • 谢谢!但是,我收到消息“方法 quote(String) 未定义类型 Pattern”)。
    • @northerner 它是在 Java 5.0 中添加的,您使用的是哪个版本的 Java?
    【解决方案2】:

    可以这样试试:

    for(int i = 0; i < text.length; i++) {
        String[] words = text[i].split("\\s+");
        for (String word : words) 
            if(word.equalsIgnoreCase(search)) {
                counter++;
                break;
            }
    }
    

    【讨论】:

      【解决方案3】:

      如果单词用空格分隔,那么你可以这样做:

      if((" "+text[i].toLowerCase()+" ").contains(" "+search+" "))
      {
         ...
      }
      

      这会在原始字符串中添加两个空格。
      例如:"this is a" 变为 " this is a "

      然后它会搜索带有侧翼空格的单词。 eg: 当search"a" 时搜索" a "

      【讨论】:

      • 如果a在开头还是结尾呢?
      • @Nadir 这正是我们添加空格的原因!
      • @Nadir 看到这个:" " +text[i].toLowerCase()+ " "
      • 相当低效,必须为每次检查创建 2 个新字符串,而您只能使用正则表达式
      • 如果单词以新行开头怎么办?比如“你好\nworld”
      【解决方案4】:
      Arrays.asList("this is a banana".split(" ")).stream().filter((s) -> s.equals("a")).count();
      

      【讨论】:

        【解决方案5】:

        当然,正如其他人所写的,您可以开始尝试各种模式来匹配“文本”中的“单词”。

        但问题是:根据您必须解决的潜在问题,这可能(到目前为止)还不够好。含义:您是否面临在某个字符串中找到某种模式的问题......或者您是否真的想以“人类语言”的方式解释该文本?你知道,当有人写下文字时,可能会有细微的错别字、奇怪的字符;各种使在该文本中真正“找到”某个单词变得困难的东西。除非您深入研究事物的“语言处理”方面。

        长话短说:如果你的工作是“找出字符串中的某些模式”;那么所有其他答案都可以。但是,如果您的要求超出此范围,例如“有人将使用您的应用程序来‘搜索’巨大的数据集”;那么你最好现在停下来;并考虑转向支持全文的搜索引擎,如 ElasticSearch 或 Solr。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-01-25
          • 1970-01-01
          • 2011-11-09
          • 2013-05-18
          • 2021-12-20
          • 2013-12-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多