En java, comment obtenir une sous-chaîne d'une chaîne à un caractère c?

102

J'ai une chaîne (qui est essentiellement un nom de fichier suivant une convention de dénomination) abc.def.ghi

Je voudrais extraire la sous-chaîne avant la première .(c'est-à-dire un point)

Dans java doc api, je n'arrive pas à trouver une méthode dans String qui fait cela.
Est-ce que je manque quelque chose? Comment faire?

xyz
la source

Réponses:

64

regardez String.indexOfet String.substring.

Assurez-vous de vérifier -1 pour indexOf.

TofuBière
la source
1
court et doux. Rappelez-vous également que indexOf donne le premier index de la sous-chaîne.
Neil Chowdhury
112

La réponse acceptée est correcte mais elle ne vous dit pas comment l'utiliser. C'est ainsi que vous utilisez conjointement les fonctions indexOf et substring.

String filename = "abc.def.ghi";     // full file name
int iend = filename.indexOf("."); //this finds the first occurrence of "." 
//in string thus giving you the index of where it is in the string

// Now iend can be -1, if lets say the string had no "." at all in it i.e. no "." is found. 
//So check and account for it.

String subString;
if (iend != -1) 
{
    subString= filename.substring(0 , iend); //this will give abc
}
Sam B
la source
1
Ce code n'est pas valide car vous ne pouvez pas placer une déclaration de variable dans le corps d'une instruction If sans accolades.
Clashsoft
85

Vous pouvez simplement diviser la chaîne.

public String[] split(String regex)

Notez que java.lang.String.split utilise la valeur d'expression régulière du délimiteur. En gros comme ça ...

String filename = "abc.def.ghi";     // full file name
String[] parts = filename.split("\\."); // String array, each element is text between dots

String beforeFirstDot = parts[0];    // Text before the first dot

Bien sûr, cela est divisé en plusieurs lignes pour la clairité. Cela pourrait être écrit comme

String beforeFirstDot = filename.split("\\.")[0];
Chad Schouggins
la source
5
Votre proposition n'est pas correcte, car java.lang.String.split prend la valeur regex comme attribut, pas seulement comme une chaîne. Tout "." dans votre exemple doivent être remplacés par "\\". Ensuite, ça marchera :)
Erik Kaju
2
J'adore les regex, mais cela me touche à chaque fois.
Chad Schouggins
71

Si votre projet utilise déjà commons-lang , StringUtils fournit une méthode intéressante à cet effet:

String filename = "abc.def.ghi";

String start = StringUtils.substringBefore(filename, "."); // returns "abc"

voir javadoc [2.6] [3.1]

Max Fichtelmann
la source
Plus propre que les autres solutions.
userab
12

ou vous pouvez essayer quelque chose comme

"abc.def.ghi".substring(0,"abc.def.ghi".indexOf(c)-1);

Umer Hayat
la source
3
plantera de 'c' n'est pas dans la chaîne car indexOf retournera -1
TofuBeer
@Umer Hayat Et si le nom du fichier est def.hij.klm? Comment votre code fonctionnerait-il alors? (Votre code ne fonctionne que pour cet exemple - vous pourriez aussi bien écrire une fonction qui renvoie "abc"- cela fonctionnerait tout aussi bien)
Bohème
@Bohemian: Je sais qu'il y a des cas limites et des contrôles manquants. C'était une réponse spécifique à la question spécifique et l'idée était de donner une idée générale à travers un exemple :).
Umer Hayat
1
@TofuBeer: Ok, d'accord, il y a une confusion plus tôt "(c'est-à-dire un point)" n'était pas là dans le message réel. Je pense et j'espère que ma réponse donne une idée générale pour résoudre ce type de problème.
Umer Hayat
2
J'irais avec: int ix = inString.indexOf ('.'); if (ix> -1) inString = inString.substring (0, ix); Je ne sais pas pourquoi Umer a suggéré de soustraire 1. Le deuxième argument de sous-chaîne est de toute façon mais excluant de toute façon.
Micha Berger
4

Que diriez-vous d'utiliser regex?

String firstWord = filename.replaceAll("\\..*","")

Cela remplace tout du premier point à la fin par "" (c'est-à-dire qu'il l'efface, vous laissant avec ce que vous voulez)

Voici un test:

System.out.println("abc.def.hij".replaceAll("\\..*", "");

Production:

abc
Bohème
la source
7
Je n'ai pas voté contre, (et je suis d'accord que ça craint que les gens ne votent sans raison) mais votre solution est assez chère et pas super évidente.
TofuBeer
1
@ Knickerless-Noggins Je peux le décrire, si vous voulez des détails, je peux le faire aussi ... mais je ne sais pas comment je pourrais le faire dans un commentaire (peut-être devoir faire une autre question / réponse). C'est cher car cela crée une toute nouvelle chaîne avec tous les caractères de remplacement. substring renvoie simplement une vue dans la chaîne. Cette aide?
TofuBeer
2
@TofuBeer vous vous trompez. Les chaînes sont immuables . La sous-chaîne ne renvoie pas de vue. Chaque String renvoyé par une méthode String est un nouveau String.
Bohème
@ Knickerless-Noggins Il se trompe ... Voir les commentaires récents. En outre, c'est assez efficace. La densité de code est élevée - elle devrait être utilisée intensément pour justifier l'ajout de code supplémentaire pour des raisons de «performances».
Bohème
Il a apparemment changé dans JDK 7, javarevisited.blogspot.ca/2011/10/…
TofuBeer
2

Dans java.lang.String, vous obtenez des méthodes comme indexOf (): qui vous renvoie le premier index d'un char / string. et lstIndexOf: qui vous renvoie le dernier index de String / char

Depuis Java Doc:

  public int indexOf(int ch)
  public int indexOf(String str)

Renvoie l'index dans cette chaîne de la première occurrence du caractère spécifié.

Swagatika
la source
2

Voici le code qui retourne une sous-chaîne de a Stringà l'un d'une liste de caractères donnée:

/**
 * Return a substring of the given original string until the first appearance
 * of any of the given characters.
 * <p>
 * e.g. Original "ab&cd-ef&gh"
 * 1. Separators {'&', '-'}
 * Result: "ab"
 * 2. Separators {'~', '-'}
 * Result: "ab&cd"
 * 3. Separators {'~', '='}
 * Result: "ab&cd-ef&gh"
 *
 * @param original   the original string
 * @param characters the separators until the substring to be considered
 * @return the substring or the original string of no separator exists
 */
public static String substringFirstOf(String original, List<Character> characters) {
    return characters.stream()
            .map(original::indexOf)
            .filter(min -> min > 0)
            .reduce(Integer::min)
            .map(position -> original.substring(0, position))
            .orElse(original);
}
m3th0dman
la source
1

Cela pourrait aider:

public static String getCorporateID(String fileName) {

    String corporateId = null;

    try {
        corporateId = fileName.substring(0, fileName.indexOf("_"));
        // System.out.println(new Date() + ": " + "Corporate:
        // "+corporateId);
        return corporateId;
    } catch (Exception e) {
        corporateId = null;
        e.printStackTrace();
    }

    return corporateId;
}
Vinod Moyal
la source