web-dev-qa-db-fra.com

Comment trouver le premier caractère après le deuxième point java

Avez-vous une idée de comment obtenir le premier caractère après second point de la chaîne?.

String str1 = "test.1231.asdasd.cccc.2.a.2";
String str2 = "aaa.1.22224.sadsada";

Dans le premier cas, je devrais obtenir a et dans le deuxième 2. , Je pensais diviser une chaîne de caractères par un point et extraire le premier caractère du troisième élément. Mais cela semble trop compliqué et je pense qu'il existe un meilleur moyen.

6
Suule

Que diriez-vous d'une regex pour cela?

Pattern p = Pattern.compile(".+?\\..+?\\.(\\w)");
Matcher m = p.matcher(str1);

if (m.find()) {
     System.out.println(m.group(1));
}

La regex dit: trouvez n'importe quoi une ou plusieurs fois de manière non gourmande (.+?), qui doit être suivi d'un point (\\.), puis encore une fois tout ce qui est une ou plusieurs fois de façon non gourmande (.+?) suivi d'un point (\\.). Une fois que cela a été mis en correspondance, prenez le premier caractère Word du premier groupe ((\\w)). 

10
Eugene

Habituellement, regex fera un excellent travail ici. Si vous recherchez quelque chose de plus personnalisable, envisagez la mise en œuvre suivante:

private static int positionOf(String source, String target, int match) {
    if (match < 1) {
        return -1;
    }
    int result = -1;

    do {
        result = source.indexOf(target, result + target.length());
    } while (--match > 0 && result > 0);

    return result;
}

et ensuite le test est fait avec:

String str1 = "test..1231.asdasd.cccc..2.a.2.";

System.out.println (positionOf (str1, ".", 3)); -> // imprime 10
System.out.println (positionOf (str1, "c", 4)); -> // imprime 21
System.out.println (positionOf (str1, "c", 5)); -> // impressions -1
System.out.println (positionOf (str1, "..", 2)); -> // empreintes 22 -> n'oubliez pas que le premier symbole après la correspondance est à la position 22 + target.length () et qu'il peut ne pas y avoir d'élément avec un tel indice dans le tableau char.

2
dbl

Sans utiliser pattern, vous pouvez utiliser les méthodes subString et charAt de la classe String pour y parvenir.

// You can return String instead of char
public static char returnSecondChar(String strParam) {
    String tmpSubString = "";
   // First check if . exists in the string.
    if (strParam.indexOf('.') != -1) {
        // If yes, then extract substring starting from .+1  
        tmpSubString = strParam.substring(strParam.indexOf('.') + 1);
        System.out.println(tmpSubString);

       // Check if second '.' exists
        if (tmpSubString.indexOf('.') != -1) {

            // If it exists, get the char at index of . + 1  
            return tmpSubString.charAt(tmpSubString.indexOf('.') + 1);
        }
    }
    // If 2 '.' don't exists in the string, return '-'. Here you can return any thing
    return '-';
}
2
Ashishkumar Singh

Vous pouvez le faire en divisant la String comme ceci:

public static void main(String[] args) {
    String str1 = "test.1231.asdasd.cccc.2.a.2";
    String str2 = "aaa.1.22224.sadsada";

    System.out.println(getCharAfterSecondDot(str1));
    System.out.println(getCharAfterSecondDot(str2));
}

public static char getCharAfterSecondDot(String s) {
    String[] split = s.split("\\.");
    // TODO check if there are values in the array!
    return split[2].charAt(0);
}

Je ne pense pas que ce soit trop compliqué, mais utiliser un regex qui correspond directement est de toute façon une très bonne (peut-être meilleure) solution.

Veuillez noter qu'il pourrait y avoir le cas d'une entrée String avec moins de deux points, qui devrait être traitée (voir TODO commentaire dans le code).

1
deHaar

Vous pouvez utiliser l'API Java Stream depuis Java 8:

String string = "test.1231.asdasd.cccc.2.a.2";
Arrays.stream(string.split("\\."))                 // Split by dot
      .skip(2).limit(1)                            // Skip 2 initial parts and limit to one
      .map(i -> i.substring(0, 1))                 // Map to the first character
      .findFirst().ifPresent(System.out::println); // Get first and print if exists

Cependant, je vous recommande de vous en tenir à Regex, ce qui est plus sûr et correct:


Voici le Regex dont vous avez besoin (démo disponible à Regex101 ):

.*?\..*?\.(.).*

N'oubliez pas d'échapper aux caractères spéciaux avec \\ à double barre oblique.

String[] array = new String[3];
array[0] = "test.1231.asdasd.cccc.2.a.2";
array[1] = "aaa.1.22224.sadsada";
array[2] = "test";

Pattern p = Pattern.compile(".*?\\..*?\\.(.).*");
for (int i=0; i<array.length; i++) {
    Matcher m = p.matcher(array[i]);
    if (m.find()) {
         System.out.println(m.group(1));
    }
}

Ce code imprime deux résultats sur chaque ligne: a, 2 et une voie vide car sur la 3ème chaîne, il n'y a pas de correspondance.

1
Nikolas

Une solution simple utilisant String.indexOf:

public static Character getCharAfterSecondDot(String s) {
    int indexOfFirstDot = s.indexOf('.');
    if (!isValidIndex(indexOfFirstDot, s)) {
        return null;
    }

    int indexOfSecondDot = s.indexOf('.', indexOfFirstDot + 1);
    return isValidIndex(indexOfSecondDot, s) ?
            s.charAt(indexOfSecondDot + 1) :
            null;
}

protected static boolean isValidIndex(int index, String s) {
    return index != -1 && index < s.length() - 1;
}

Utiliser indexOf(int ch) et indexOf(int ch, int fromIndex) n'a besoin d'examiner que tous les caractères dans le pire des cas.

Et une deuxième version implémentant la même logique en utilisant indexOf avec Optional:

public static Character getCharAfterSecondDot(String s) {
    return Optional.of(s.indexOf('.'))
            .filter(i -> isValidIndex(i, s))
            .map(i -> s.indexOf('.', i + 1))
            .filter(i -> isValidIndex(i, s))
            .map(i -> s.charAt(i + 1))
            .orElse(null);
}
0
LuCio