Comment trouver nième occurrence de caractère dans une chaîne de caractères?

semblable à une question affichée ici , je regarde pour une solution en Java.

Qui est, comment trouver l'index de la nième occurrence d'un caractère ou chaîne de caractères à partir d'une chaîne?

Exemple: " /dossier1/dossier2/dossier3/ ". Dans ce cas, si je demande la 3ème occurrence de slash ( / ), il apparaît avant le folder3, et je m'attends à retourner cette position d'index. Mon intention est de le soustraire de la nième occurrence d'un caractère.

Existe-t-il une méthode pratique/prête à l'emploi disponible dans L'API Java ou avons-nous besoin d'écrire une petite logique nous-mêmes pour résoudre ce problème?

aussi,

  1. j'ai rapidement cherché à savoir si une méthode était prise en charge à cet effet dans le StringUtils D'Apache Commons Lang , mais je n'en trouve aucune.
  2. peut expressions régulières aider à cet égard?
76
demandé sur Community 2010-10-20 13:57:55

16 réponses

si votre projet dépend déjà D'Apache Commons vous pouvez utiliser StringUtils.ordinalIndexOf , sinon, voici une implémentation:

public static int ordinalIndexOf(String str, String substr, int n) {
    int pos = str.indexOf(substr);
    while (--n > 0 && pos != -1)
        pos = str.indexOf(substr, pos + 1);
    return pos;
}

Ce post a été réécrit un article ici .

114
répondu aioobe 2016-11-03 07:10:00

je crois que la solution la plus facile pour trouver la nième occurrence d'une chaîne est d'utiliser des StringUtils .ordinalIndexOf () de Apache Commons.

exemple:

StringUtils.ordinalIndexOf("aabaabaa", "b", 2)  == 5
53
répondu Al Belsky 2014-02-17 16:08:54

deux options simples se produisent:

  • Utiliser charAt() à plusieurs reprises
  • Utiliser indexOf() à plusieurs reprises

par exemple:

public static int nthIndexOf(String text, char needle, int n)
{
    for (int i = 0; i < text.length(); i++)
    {
        if (text.charAt(i) == needle)
        {
            n--;
            if (n == 0)
            {
                return i;
            }
        }
    }
    return -1;
}

qui pourrait bien ne pas fonctionner aussi bien que l'utilisation de indexOf à plusieurs reprises, mais il est peut-être plus simple d'obtenir le droit.

27
répondu Jon Skeet 2010-10-20 10:01:00

Vous pouvez essayer quelque chose comme ceci:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Main {
    public static void main(String[] args) {
      System.out.println(from3rd("/folder1/folder2/folder3/"));
    }

    private static Pattern p = Pattern.compile("(/[^/]*){2}/([^/]*)");

    public static String from3rd(String in) {
        Matcher m = p.matcher(in);

        if (m.matches())
            return m.group(2);
        else
            return null;
    }
}

notez que j'ai fait quelques hypothèses dans le regex:

  • le chemin d'entrée est absolu (i.e. commence par"/");
  • vous n'avez pas besoin de la 3e "/" dans le résultat.

comme demandé dans un commentaire, je vais essayer d'expliquer le regex: (/[^/]*){2}/([^/]*)

Regular expression visualization

  • /[^/]* est un / suivi de [^/]* (n'importe quel nombre de caractères qui ne sont pas un / ),
  • (/[^/]*) regroupe l'expression précédente dans une seule entité. C'est le groupe 1 st de l'expression,
  • (/[^/]*){2} signifie que le groupe doit correspondre extérieurement à {2} times,
  • [^/]* est de nouveau un nombre quelconque de caractères qui ne sont pas un / ,
  • ([^/]*) groupes de la previos expression dans une seule entité. C'est le groupe 2 nd de l'expression.

de cette façon, vous n'avez qu'à obtenir le substrat qui correspond au 2e groupe: return m.group(2);

image courtoisie de Debuggex

14
répondu andcoz 2015-09-17 11:37:17

j'ai fait quelques changements à la réponse d'aioobe et j'ai eu une version de latindexof, et j'ai corrigé quelques problèmes NPE. Voir code ci-dessous:

public int nthLastIndexOf(String str, char c, int n) {
        if (str == null || n < 1)
            return -1;
        int pos = str.length();
        while (n-- > 0 && pos != -1)
            pos = str.lastIndexOf(c, pos - 1);
        return pos;
}
8
répondu Goofy 2012-10-24 08:33:48
 ([.^/]*/){2}[^/]*(/)

Correspondent à rien de ce suivi de / deux fois, puis de nouveau. Le troisième est celui que vous voulez

l'état Matcher peut être utilisé pour indiquer où le dernier / est

5
répondu The Archetypal Paul 2010-10-20 10:02:21
public static int nth(String source, String pattern, int n) {

   int i = 0, pos = 0, tpos = 0;

   while (i < n) {

      pos = source.indexOf(pattern);
      if (pos > -1) {
         source = source.substring(pos+1);
         tpos += pos+1;
         i++;
      } else {
         return -1;
      }
   }

   return tpos - 1;
}
3
répondu Saul 2010-10-20 10:21:58

Aujourd'hui, il y a le soutien D'Apache Lang de Commons StringUtils ,

c'est la primitive:

int org.apache.commons.lang.StringUtils.ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal)

pour votre problème vous pouvez coder ce qui suit: StringUtils.ordinalIndexOf(uri, "/", 3)

vous pouvez également trouver la dernière occurrence d'un caractère dans une chaîne de caractères avec la méthode lastOrdinalIndexOf .

3
répondu Chexpir 2014-01-24 15:20:44

une autre approche:

public static void main(String[] args) {
    String str = "/folder1/folder2/folder3/"; 
    int index = nthOccurrence(str, '/', 3);
    System.out.println(index);
}

public static int nthOccurrence(String s, char c, int occurrence) {
    return nthOccurrence(s, 0, c, 0, occurrence);
}

public static int nthOccurrence(String s, int from, char c, int curr, int expected) {
    final int index = s.indexOf(c, from);
    if(index == -1) return -1;
    return (curr + 1 == expected) ? index : 
        nthOccurrence(s, index + 1, c, curr + 1, expected);
}
2
répondu Marimuthu Madasamy 2010-10-21 04:16:37

cette réponse améliore la réponse de @aioobe. Deux bugs dans cette réponse ont été corrigés.

1. n = 0 devrait retourner -1.

2. la nième occurrence est revenue -1, mais elle a fonctionné sur les n-1èmes occurences.

essayez ça !

    public int nthOccurrence(String str, char c, int n) {
    if(n <= 0){
        return -1;
    }
    int pos = str.indexOf(c, 0);
    while (n-- > 1 && pos != -1)
        pos = str.indexOf(c, pos+1);
    return pos;
}
2
répondu Akshayraj Kore 2015-08-05 20:07:40
public class Sam_Stringnth {

    public static void main(String[] args) {
        String str="abcabcabc";
        int n = nthsearch(str, 'c', 3);
        if(n<=0)
            System.out.println("Character not found");
        else
            System.out.println("Position is:"+n);
    }
    public static int nthsearch(String str, char ch, int n){
        int pos=0;
        if(n!=0){
            for(int i=1; i<=n;i++){
                pos = str.indexOf(ch, pos)+1;
            }
            return pos;
        }
        else{
            return 0;
        }
    }
}
1
répondu SAN 2014-09-09 14:58:22

peut-être que vous pourriez atteindre ceci par la chaîne.Split.(. méthode également.

String str = "";
String[] tokens = str.split("/")
return tokens[nthIndex] == null 
1
répondu Murali 2018-01-12 15:59:55
/* program to find nth occurence of a character */

import java.util.Scanner;

public class CharOccur1
{

    public static void main(String arg[])
    {
        Scanner scr=new Scanner(System.in);
        int position=-1,count=0;
        System.out.println("enter the string");
        String str=scr.nextLine();
        System.out.println("enter the nth occurence of the character");
        int n=Integer.parseInt(scr.next());
        int leng=str.length();
        char c[]=new char[leng];
        System.out.println("Enter the character to find");
        char key=scr.next().charAt(0);
        c=str.toCharArray();
        for(int i=0;i<c.length;i++)
        {
            if(c[i]==key)
            {
                count++;
                position=i;
                if(count==n)
                {
                    System.out.println("Character found");
                    System.out.println("the position at which the " + count + " ocurrence occurs is " + position);
                    return;
                }
            }
        }
        if(n>count)
        { 
            System.out.println("Character occurs  "+ count + " times");
            return;
        }
    }
}
0
répondu Rose 2013-03-20 19:21:17

ma solution:

/**
 * Like String.indexOf, but find the n:th occurance of c
 * @param s string to search
 * @param c character to search for
 * @param n n:th character to seach for, starting with 1
 * @return the position (0-based) of the found char, or -1 if failed
 */

public static int nthIndexOf(String s, char c, int n) {
    int i = -1;
    while (n-- > 0) {
        i = s.indexOf(c, i + 1);
        if (i == -1)
            break;
    }
    return i;
}
0
répondu Per Lindberg 2015-09-16 12:43:22

le code renvoie les positions de nième occurrence en soustrayant la largeur de champ aka. Exemple. si la chaîne "débordement de Pile faible melow" est la chaîne à rechercher 2ème occurance de jeton "faible", vous serez d'accord avec moi que c'2ème occurrence est à subtring "18 et 21" . indexOfOccurance("débordement de Pile faible melow", faible, 2) retourne le 18 et le 21 dans une chaîne de caractères.

class Example{
    public Example(){
    }
            public String indexOfOccurance(String string, String token, int nthOccurance) {
                    int lengthOfToken = token.length();
                    int nthCount = 0;
                    for (int shift = 0,count = 0; count < string.length() - token.length() + 2; count++, shift++, lengthOfToken++)
                        if (string.substring(shift, lengthOfToken).equalsIgnoreCase(token)) { 
                    // keeps count of nthOccurance
                            nthCount++; 
                        if (nthCount == nthOccurance){
                    //checks if nthCount  == nthOccurance. If true, then breaks 
                             return String.valueOf(shift)+ " " +String.valueOf(lengthOfToken);   
                        }  
                    }
                    return "-1";
                }
    public static void main(String args[]){
    Example example = new Example();
    String string = "the man, the woman and the child";
    int nthPositionOfThe = 3;
   System.out.println("3rd Occurance of the is at " + example.indexOfOccurance(string, "the", nthPositionOfThe));
    }
    }
0
répondu 2016-01-29 19:56:54

//en c++ pur

int pos = 0;
for ( int i = 0; i < N; ++i ) // N = nth position
{
  pos = STRING.find( delim, pos + size_of_delim );
}
-1
répondu Shebin 2013-08-29 12:35:14