在java中的字符串中找到第n次出现的子字符串?

Posted

技术标签:

【中文标题】在java中的字符串中找到第n次出现的子字符串?【英文标题】:find the nth occurence of a substring in a string in java? 【发布时间】:2011-08-06 09:29:43 【问题描述】:

我有一个字符串,它是一个 html 页面的完整内容,我正在尝试查找 </table> 的第二次出现的索引。有没有人对如何实现这一点有任何建议?

【问题讨论】:

@Jon:你怎么知道这是作业? @Tijo:是吗?或者您是否尝试在您正在编写的真实程序中执行此操作。作业只要你说就好。 我想它和这些类似 ;) google.co.uk/… 我的问题有什么问题吗..?我有一个字符串,它是一个 hhtml 页面的完整内容。我想知道“”我第二次出现的索引 ... @T.J.我认为大多数编写真实程序的人都能够查看download.oracle.com/javase/6/docs/api/java/lang/String.html 并在此页面上搜索单词occurrence。并找出单词occurrence的出现标记最合适的功能。 @T.J.Crowder :homework..?????你的意思..?是的,我正在尝试在一个正在工作的真实项目中实现这一点,.. 【参考方案1】:

@BasVanDenBroek's answer 的泛化,使用 indexOf:

public static int nthIndexOf(String source, String sought, int n) 
    int index = source.indexOf(sought);
    if (index == -1) return -1;

    for (int i = 1; i < n; i++) 
        index = source.indexOf(sought, index + 1);
        if (index == -1) return -1;
    
    return index;

快速而肮脏的测试:

public static void main(String[] args) throws InterruptedException 
    System.out.println(nthIndexOf("abc abc abc", "abc", 1));
    System.out.println(nthIndexOf("abc abc abc", "abc", 2));
    System.out.println(nthIndexOf("abcabcabc", "abc", 2));
    System.out.println(nthIndexOf("abcabcabc", "abc", 3));
    System.out.println(nthIndexOf("abc abc abc", "abc", 3));
    System.out.println(nthIndexOf("abc abc defasabc", "abc", 3));
    System.out.println(nthIndexOf("abc abc defasabc", "abc", 4));

【讨论】:

这个比公认的解决方案更好,因为另一个使用模式匹配,因此速度很慢。这个速度快了两个数量级【参考方案2】:

这是一个有趣的镜头;)

public static int findNthIndexOf (String str, String needle, int occurence)
            throws IndexOutOfBoundsException 
    int index = -1;
    Pattern p = Pattern.compile(needle, Pattern.MULTILINE);
    Matcher m = p.matcher(str);
    while(m.find()) 
        if (--occurence == 0) 
            index = m.start();
            break;
        
    
    if (index < 0) throw new IndexOutOfBoundsException();
    return index;

【讨论】:

不是正则表达式中应该转义的 fon.hum.uva.nl/praat/manual/Regular_expressions_3__Anchors.html @Bas - 不,它不是 Java 正则表达式中的特殊字符:download.oracle.com/javase/6/docs/api/java/util/regex/…【参考方案3】:

查找第 N 次出现的字符串的另一个好选择是使用来自 Apache Commons 的 StringUtils.ordinalIndexOf():

StringUtils.ordinalIndexOf("aabaabaa", "b", 2)  == 5

【讨论】:

+1,因为最好不要重新发明***。 不是“另一个好选择”,只是最好/最安全/最快的选择。谢谢。【参考方案4】:

首先找到第一个索引,然后从第一个索引+1开始查找第二个索引

String string = "first</table>second</table>";
int firstIndex = string.indexOf("</table>");
int secondIndex = string.indexOf("</table>", firstIndex+1);
System.out.println("second index: " + secondIndex);

顺便说一句,这是一些非常基本的代码,您需要构建一些额外的检查(索引!= -1 等) 同样在您的帖子标题中,它说第 n 次出现,但在您的帖子中您特别提到了第二次出现。如果你真的需要第 n 次出现,我相信你可以从这里弄清楚。

【讨论】:

【参考方案5】:

在https://***.com/a/5678546/15789 和https://***.com/a/14356988/15789 上进一步工作(感谢原始海报@sebastiaan-van-den-broek 和@assylias)。

获取数组中的所有索引。然后你可以得到任何第 n 个索引。在许多情况下,可能需要多次获取字符串中子字符串的第 n 个索引。一次获取一个数组并多次访问它可能更容易。

public static int[] getIndices(String source, String substr) 
    List<Integer> indicesList = null;
    int index = source.indexOf(substr);
    if (index == -1) 
        return new int[0];
     else 
        indicesList = new ArrayList<>();
        indicesList.add(index);
    

    while (index != -1) 
        index = source.indexOf(substr, index + 1);
        if (index != -1) 
            indicesList.add(index);
        
    

    // Integer[] iarr = new int[1]; 
    //Autoboxing does not work with arrays. Run loop to convert. 
    //toArray does not convert Integer[] to int[]
    int[] indices = new int[indicesList.size()];
    for (int i = 0; i < indicesList.size(); i++) 
        indices[i] = indicesList.get(i);
    
    return indices;

【讨论】:

以上是关于在java中的字符串中找到第n次出现的子字符串?的主要内容,如果未能解决你的问题,请参考以下文章

从字符串中查找 C++ 第 n 次出现的子字符串

查找字符串中第 n 次出现的子字符串

替换字符串中第 n 次出现的子字符串

Java如何计数替换字符串中第一次出现的子字符串?

怎么查找一个string 字符串中的子字符串出现的次数和位置

SQL String - 删除2次出现之间的子字符串