字符串中子字符串的出现

117 java string

为什么以下算法不会停止?(str是我正在搜索的字符串,findStr是我想要查找的字符串)

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;

while (lastIndex != -1) {
    lastIndex = str.indexOf(findStr,lastIndex);

    if( lastIndex != -1)
        count++;

    lastIndex += findStr.length();
}

System.out.println(count);
Run Code Online (Sandbox Code Playgroud)

A_M*_*A_M 179

如何使用Apache Commons Lang的StringUtils.countMatches

String str = "helloslkhellodjladfjhello";
String findStr = "hello";

System.out.println(StringUtils.countMatches(str, findStr));
Run Code Online (Sandbox Code Playgroud)

那输出:

3
Run Code Online (Sandbox Code Playgroud)

  • 无论这个建议多么正确,它都不能被接受为解决方案,因为它没有回答OP的问题 (9认同)
  • 这是不赞成使用的东西..我的IDE无法识别 (3认同)

Oli*_*ier 114

lastIndex += findStr.length();被放在括号外面,造成一个无限循环(当没有发现时,lastIndex总是如此findStr.length()).

这是固定版本:

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;

while (lastIndex != -1) {

    lastIndex = str.indexOf(findStr, lastIndex);

    if (lastIndex != -1) {
        count++;
        lastIndex += findStr.length();
    }
}
System.out.println(count);
Run Code Online (Sandbox Code Playgroud)


Pet*_*rey 86

更短的版本.;)

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
System.out.println(str.split(findStr, -1).length-1);
Run Code Online (Sandbox Code Playgroud)

  • `return haystack.split(Pattern.quote(needle), - 1.).length - 1;`if例如`needle =":)"` (8认同)
  • 太好了!但它只包括非重叠的匹配,不是吗?例如,在"aaa"中匹配"aa"将返回1,而不是2?当然,包括重叠或非重叠匹配都是有效的,并且取决于用户要求(可能是一个表示计数重叠的标志,是/否)? (4认同)
  • 哎呀,谢谢,很高兴知道!这将教会我阅读javadoc中的小行... (3认同)
  • @lOranger没有`,-1`它将丢弃尾随匹配. (2认同)
  • -1 ..尝试在"aaaa"和"aa"上运行它.正确的答案是3而不是2. (2认同)

cod*_*ach 82

最后一行是造成问题.lastIndex永远不会在-1,所以会有一个无限循环.这可以通过将最后一行代码移动到if块来修复.

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;

while(lastIndex != -1){

    lastIndex = str.indexOf(findStr,lastIndex);

    if(lastIndex != -1){
        count ++;
        lastIndex += findStr.length();
    }
}
System.out.println(count);
Run Code Online (Sandbox Code Playgroud)

  • 这个回复是我在一小时前发的帖子的确切副本;) (111认同)
  • 请注意,这可能会也可能不会返回预期的结果.使用子字符串"aa"和字符串来搜索"aaa"时,预期出现的次数可能是1(由此代码返回),但也可能是两次(在这种情况下,您需要"lastIndex ++"而不是"lastIndex + = findStr.length()")取决于你要找的东西. (8认同)
  • 这里的寓意是,如果您打算写一个答案,请先检查 _first_ 是否其他人已经写了完全相同的答案。无论您的答案是复制的还是独立编写的,让相同的答案出现两次确实没有任何好处。 (3认同)
  • 人们什么时候才能学会将这样的东西包装在复制和粘贴静态方法中?请参阅下面我的答案,它也更加优化。 (2认同)

Jea*_*ean 79

你真的必须自己处理匹配吗?特别是如果你需要的只是出现次数,正则表达式更整洁:

String str = "helloslkhellodjladfjhello";
Pattern p = Pattern.compile("hello");
Matcher m = p.matcher(str);
int count = 0;
while (m.find()){
    count +=1;
}
System.out.println(count);     
Run Code Online (Sandbox Code Playgroud)

  • 是的,如果你正确地表达你的正则表达式.尝试使用`Pattern.compile("hel \\ + lo");````符号在正则表达式中有特殊含义,需要进行转义. (13认同)
  • 如果您正在寻找的是采用任意String并将其用作与忽略的所有特殊正则表达式字符的完全匹配,那么`Pattern.quote(str)`就是您的朋友! (4认同)
  • 当str ="aaaaaa"时,这对"aaa"不起作用.有4个答案,但你的答案是2 (2认同)

mom*_*omo 9

在这里,它包含在一个漂亮且可重用的方法中:

public static int count(String text, String find) {
        int index = 0, count = 0, length = find.length();
        while( (index = text.indexOf(find, index)) != -1 ) {                
                index += length; count++;
        }
        return count;
}
Run Code Online (Sandbox Code Playgroud)


dfa*_*dfa 8

String str = "helloslkhellodjladfjhello";
String findStr = "hello";
int lastIndex = 0;
int count = 0;

while((lastIndex = str.indexOf(findStr, lastIndex)) != -1) {
     count++;
     lastIndex += findStr.length() - 1;
}
System.out.println(count);
Run Code Online (Sandbox Code Playgroud)

循环结束时计数为3; 希望能帮助到你

  • 代码包含错误.如果我们搜索单个字符,`findStr.length() - 1`将返回0并且我们处于无限循环中. (5认同)

kme*_*cpp 8

我很惊讶没有人提到这一支班轮。它简单,简洁,并且比str.split(target, -1).length-1

public static int count(String str, String target) {
    return (str.length() - str.replace(target, "").length()) / target.length();
}
Run Code Online (Sandbox Code Playgroud)

  • 应该是最佳答案。谢谢你! (4认同)
  • @Attila当然会...就像如果 str 或 target 为 null 时它会抛出 NullPointerException 一样。计算空字符串有什么意义? (4认同)
  • 完美的答案! (3认同)

ben*_*nkc 6

许多给定的答案在以下一个或多个方面失败:

  • 任意长度的图案
  • 重叠匹配(例如"23232"中的"232"或"aaa"中的"aa")
  • 正则表达式元字符

这是我写的:

static int countMatches(Pattern pattern, String string)
{
    Matcher matcher = pattern.matcher(string);

    int count = 0;
    int pos = 0;
    while (matcher.find(pos))
    {
        count++;
        pos = matcher.start() + 1;
    }

    return count;
}
Run Code Online (Sandbox Code Playgroud)

示例电话:

Pattern pattern = Pattern.compile("232");
int count = countMatches(pattern, "23232"); // Returns 2
Run Code Online (Sandbox Code Playgroud)

如果你想要一个非正则表达式搜索,只需使用LITERAL标志适当地编译你的模式:

Pattern pattern = Pattern.compile("1+1", Pattern.LITERAL);
int count = countMatches(pattern, "1+1+1"); // Returns 2
Run Code Online (Sandbox Code Playgroud)


Vic*_*tor 6

您可以使用内置库函数的出现次数:

import org.springframework.util.StringUtils;
StringUtils.countOccurrencesOf(result, "R-")
Run Code Online (Sandbox Code Playgroud)


Mak*_*kov 6

public int countOfOccurrences(String str, String subStr) {
  return (str.length() - str.replaceAll(Pattern.quote(subStr), "").length()) / subStr.length();
}
Run Code Online (Sandbox Code Playgroud)

  • 没有正则表达式的原因,使用“replace”,而不是“replaceAll”。 (2认同)