En Java, ¿cómo obtener una subcadena de una cadena hasta un carácter c?

101

Tengo una cadena (que es básicamente un nombre de archivo que sigue una convención de nomenclatura) abc.def.ghi

Me gustaría extraer la subcadena antes de la primera .(es decir, un punto)

En java doc api, parece que no puedo encontrar un método en String que haga eso.
¿Me estoy perdiendo de algo? ¿Cómo hacerlo?

xyz
fuente

Respuestas:

65

mira String.indexOfy String.substring.

Asegúrese de comprobar -1 para indexOf.

Tofu cerveza
fuente
1
corto y dulce. También recuerde que indexOf da el primer índice de la subcadena.
Neil Chowdhury
112

La respuesta aceptada es correcta pero no le dice cómo usarla. Así es como se usan las funciones indexOf y substring juntas.

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
fuente
1
Este es un código no válido porque no puede poner una declaración de variable en el cuerpo de una declaración If sin llaves.
Clashsoft
84

Puedes simplemente dividir la cuerda ...

public String[] split(String regex)

Tenga en cuenta que java.lang.String.split usa el valor de expresión regular del delimitador. Básicamente así ...

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

Por supuesto, esto se divide en varias líneas para la clarividencia. Podría escribirse como

String beforeFirstDot = filename.split("\\.")[0];
Chad Schouggins
fuente
5
Su propuesta no es correcta, porque java.lang.String.split toma el valor regex como atributo, no solo como cadena. Todas "." en su ejemplo debe cambiarse a "\\". Entonces funcionará :)
Erik Kaju
2
Amo las expresiones regulares, pero eso me atrapa cada vez.
Chad Schouggins
70

Si su proyecto ya usa commons-lang , StringUtils proporciona un buen método para este propósito:

String filename = "abc.def.ghi";

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

ver javadoc [2.6] [3.1]

Max Fichtelmann
fuente
Más limpio que otras soluciones.
userab
12

o puedes probar algo como

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

Umer Hayat
fuente
3
se bloqueará de 'c' no está en la cadena ya que indexOf devolverá -1
TofuBeer
@Umer Hayat ¿Y si el nombre del archivo es def.hij.klm? ¿Cómo funcionaría entonces tu código? (Su código solo funciona para este ejemplo; también podría escribir una función que regrese "abc", funcionaría igual de bien)
Bohemian
@Bohemian: Sé que hay casos límite y faltan cheques. Era una respuesta específica a la pregunta específica y la idea era dar la idea general a través de un ejemplo :).
Umer Hayat
1
@TofuBeer: Ok, bien, hay una confusión que antes "(es decir, un punto)" no estaba en la publicación real. Creo y espero que mi respuesta dé una idea general para resolver este tipo de problemas.
Umer Hayat
2
Yo iría con: int ix = inString.indexOf ('.'); if (ix> -1) inString = inString.substring (0, ix); No sé por qué Umer sugirió restar 1. El segundo argumento de la subcadena es hasta pero excluyente de todos modos.
Micha Berger
4

¿Qué tal usar expresiones regulares?

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

Esto reemplaza todo, desde el primer punto hasta el final con "" (es decir, lo borra, dejándote con lo que quieres)

He aquí una prueba:

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

Salida:

abc
Bohemio
fuente
7
No voté negativamente (y estoy de acuerdo en que apesta cuando la gente vota negativamente sin ningún motivo), pero su solución es bastante cara y no muy obvia.
TofuBeer
1
@ Knickerless-Noggins Puedo describirlo, si quieres detalles, también puedo hacerlo ... pero no estoy seguro de cómo podría hacerlo en un comentario (tal vez tenga que hacer otra pregunta / respuesta). Es caro porque crea una cadena completamente nueva junto con la sustitución de todos los caracteres. substring simplemente devuelve una vista en la cadena. ¿Que ayuda?
TofuBeer
2
@TofuBeer es incorrecto. Las cuerdas son inmutables . La subcadena no devuelve una vista. Cada String devuelto por un método String es un String nuevo .
Bohemio
@ Knickerless-Noggins Se equivoca ... Ver comentarios recientes. Además, es lo suficientemente eficaz. La densidad del código es alta; tendría que usarse intensamente para justificar la adición de más código por motivos de "rendimiento".
Bohemio
Aparentemente cambió en JDK 7, javarevisited.blogspot.ca/2011/10/…
TofuBeer
2

En java.lang.String obtienes algunos métodos como indexOf (): que te devuelve el primer índice de un carácter / cadena. y lstIndexOf: que le devuelve el último índice de String / char

Desde Java Doc:

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

Devuelve el índice dentro de esta cadena de la primera aparición del carácter especificado.

Swagatika
fuente
2

Aquí hay un código que devuelve una subcadena desde a Stringhasta cualquiera de una lista dada de caracteres:

/**
 * 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
fuente
1

Esto podría ayudar:

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
fuente