Separar cadena con punto como delimitador

Me pregunto si voy a dividir una cadena en a . ¿la manera correcta? Mi código es:

 String[] fn = filename.split("."); return fn[0]; 

Solo necesito la primera parte de la cadena, por eso devuelvo el primer artículo. Lo pregunto porque noté en la API eso . significa cualquier personaje, así que ahora estoy atascado.

split() acepta una expresión regular, por lo que debes escapar . no considerarlo como un metacaracidor de expresiones regulares. Aquí hay un ejemplo:

 String[] fn = filename.split("\\."); return fn[0]; 

Split usa expresiones regulares, donde ‘.’ es un personaje especial que significa algo. Necesitas escapar si realmente quieres que coincida con el ‘.’ personaje:

 String[] fn = filename.split("\\."); 

(uno ” para escapar de ‘.’ en la expresión regular, y el otro para escapar del primero en la cadena Java)

Además, no recomendaría devolver fn [0] ya que si tiene un archivo llamado something.blabla.txt , que es un nombre válido, no devolverá el nombre del archivo real. En cambio, creo que es mejor si usa:

 int idx = filename.lastIndexOf('.'); return filename.subString(0, idx); 

el método String # split (String) usa expresiones regulares. En expresiones regulares, el “.” carácter significa “cualquier personaje”. Puede evitar este comportamiento escapando del “.”

 filename.split("\\."); 

o decirle al método de división que se divida en una clase de caracteres:

 filename.split("[.]"); 

Las clases de caracteres son colecciones de personajes. Podrías escribir

 filename.split("[-.;ld7]"); 

y el nombre del archivo se dividiría en cada “-“, “.”, “;”, “l”, “d” o “7”. Dentro de las clases de personajes, el “.” no es un personaje especial (“metacarácter”).

Solo veo soluciones aquí pero no hay una explicación completa del problema, así que decidí publicar esta respuesta

Problema

Necesita saber algunas cosas sobre text.split(delim) . método de split :

  1. acepta como argumento expresión regular (regex) que describe el delimitador en el que queremos dividir,
  2. si delim existe al final del text como en a,b,c,, (donde el delimitador es , ) split al principio creará una matriz como ["a" "b" "c" "" ""] pero dado que en la mayoría de los casos realmente no necesitamos estas cadenas vacías finales, también las elimina automáticamente para nosotros. Por lo tanto, crea otra matriz sin estas cadenas vacías finales y la devuelve .

También necesitas saber ese punto . es un personaje especial en regex . Representa cualquier carácter (excepto los separadores de línea, pero esto se puede cambiar con el indicador Pattern.DOTALL ).

Entonces para una cadena como "abc" si nos separamos de "." método de split

  1. crear una matriz como ["" "" "" ""] ,
  2. pero dado que esta matriz contiene solo cadenas vacías y todas están detrás, serán eliminadas (como se muestra en el segundo punto anterior)

lo que significa que obtendremos como resultado matriz vacía [] (sin elementos, ni siquiera cadena vacía), por lo que no podemos usar fn[0] porque no hay índice 0.

Solución

Para resolver este problema, simplemente necesita crear expresiones regulares que representará un punto. Para hacerlo, debemos escapar de eso . . Hay pocas maneras de hacerlo, pero la más simple es probablemente mediante el uso de \ (que en String debe escribirse como "\\" porque \ también es especial allí y requiere otro \ para ser escapado).

Entonces la solución a su problema puede parecerse

 String[] fn = filename.split("\\."); 

Prima

También puedes usar otras formas de escapar de ese punto como

  • usando split("[.]") clase de caracteres split("[.]")
  • envolviéndolo en split("\\Q.\\E") cotizaciones split("\\Q.\\E")
  • utilizando la instancia de Patrón adecuada con la bandera Pattern.LITERAL
  • o simplemente use split(Pattern.quote(".")) y deje que regex escape por usted.

Como DOT (.) Se considera un personaje especial y el método de división de String espera una expresión regular, debe hacer esto:

 String[] fn = filename.split("\\."); return fn[0]; 

En java, los caracteres especiales deben escaparse con un “\”, pero dado que “\” también es un carácter especial en Java, debes escapar de nuevo con otro “\”.

¿No sería más eficiente usar

  filename.substring(0, filename.indexOf(".")) 

si solo quieres lo que está hasta el primer punto?

Por lo general, NO es una buena idea desenmascararlo a mano. Hay un método en la clase Pattern para esta tarea:

 java.util.regex static String quote(String s) 

La división debe tomar regex como argumento … Simplemente cambie "." a "\\."

Nota: Se debe tener más cuidado con este fragmento, incluso después de que se escapó el punto.

Si filename es solo la cadena “.”, Entonces fn terminará siendo de 0 de longitud y fn [0] todavía arrojará una excepción.

Esto es, porque si el patrón coincide al menos una vez, entonces split descartará todas las cadenas vacías (por lo tanto, también la anterior al punto) de la matriz, dejando una matriz vacía que se devolverá.

split toma una expresión regular como argumento. Entonces deberías pasar "\." en lugar de "." porque "." es un metacarácter en expresiones regulares.