2010-11-01 12 views
5

Estoy tratando de hacer lo siguiente en Java
dar una ruta de directorio como "https://stackoverflow.com/a/b/c" Quiero obtener una matriz de cadena como ["a", "b", "c"]. El código es el siguiente:Java - expresión regular para dividir rutas de directorio

private static final String DIRECTORY_PATH_SEPARATOR = "/"; 
    Iterator iter = testPaths.iterator(); 

      String[] directories; 

     while(iter.hasNext()) { 

      directories = ((String) iter.next()).split(DIRECTORY_PATH_SEPARATOR); 
     } 

pero lo que obtengo como array es espacio también. Quiero obtener todas esas cadenas con length>0.
¿cómo puedo hacer eso?

Respuesta

4

El único lugar donde obtendría una cadena vacía (en una ruta válida) sería el primer elemento si la ruta comenzó con el separador. Si tenía el separador principal, divídalo en el camino sin él.

String path = "https://stackoverflow.com/a/b/c"; 
String[] directories = path.substring(1).split(DIRECTORY_PATH_SEPARATOR); 
// { "a", "b", "c" } 

Como señaló OmnipotentEntity, mi suposición era errónea sobre caminos válidos. De lo contrario, tendrías que pasar por la matriz y mantener cadenas no vacías al usar split().

String path = "https://stackoverflow.com/a/b////c"; 
String[] split = path.split(DIRECTORY_PATH_SEPARATOR); 
ArrayList<String> directories = new ArrayList<String>(split.length); 
for (String dir : split) 
    if (dir.length() > 0) 
     directories.add(dir); 

Una alternativa es el uso de expresiones regulares reales para que coincida con caracteres que no sean del separador:

String path = "https://stackoverflow.com/a/b////c"; 
ArrayList<String> directories = new ArrayList<String>(); 
Pattern regex = Pattern.compile("[^" + DIRECTORY_PATH_SEPARATOR + "]+"); 
Matcher matcher = regex.matcher(path); 
while (matcher.find()) 
    directories.add(matcher.group()); 
+0

Realmente no es cierto: "/ a // b ////// c" también es una ruta válida. – OmnipotentEntity

+0

@Omni: ¿Es realmente una ruta válida? Si es así, tendré que revisarlo. –

+0

Para cierto. Inténtalo tú mismo en un caparazón. :) Probablemente, lo mejor que se puede hacer será recorrer la matriz una vez que se haya realizado y eliminar las cadenas vacías. – OmnipotentEntity

0

Aquí es una versión no expresiones regulares más fiable que utiliza rutinas del sistema de archivos:

public static List<String> splitFilePath(final File f){ 
    if(f == null){ 
     throw new NullPointerException(); 
    } 
    final List<String> result = new ArrayList<String>(); 
    File temp = f.getAbsoluteFile(); 
    while(temp != null){ 
     result.add(0, temp.getName()); 
     temp = temp.getParentFile(); 
    } 
    return result; 
} 

Código de prueba:

public static void main(final String[] args){ 
    final File f = new File("foo/bar/phleem.txt"); 
    final List<String> parts = splitFilePath(f); 
    System.out.println(parts); 
} 

Salida:

[, hogar, seanizer, proyectos, eclipse, helios2, stackfiddler, foo, bar, phleem.txt]

me devuelven una lista porque es más fácil de usar , pero no hay nada que le impida ya sea cambiando el método para devolver una matriz o convertir el resultado desde el exterior con esto:

List<String> parts = splitFilePath(f); 
String[] partsAsArray = parts.toArray(new String[parts.size()]); 
1

El método String.split(String) no es muy flexible y sus resultados pueden ser sorprendentes (por ejemplo, descartar silenciosamente cadenas finales vacías). Estoy utilizando el Guava libraries (Google Core Bibliotecas para Java) para todos mis proyectos, y que contiene un muy buen Splitter utilidad que hace lo que quiere de una manera muy fácil de leer y predecible:

String path = "https://stackoverflow.com/a/b///c///"; 
Iterable<String> directories = Splitter 
    .on(DIRECTORY_PATH_SEPARATOR) 
    .omitEmptyStrings() 
    .split(path); 

Eso le da una iterable que se pueden utilizar directamente en un bucle como este:

for(String directory : directories) { 
    System.out.println(directory); 
} 

en ese caso, ni siquiera crear un objeto intermedio para almacenar los directorios, pero les crea sobre la marcha.

Si necesita la lista de directorios, puede copiar el iterable en un ArrayList o la matriz de la siguiente manera:

List<String> dirList = Lists.newArrayList(directories); 
String[] dirArray = Iterables.toArray(directories, String.class); 

Como nota de cierre: Para escribir código portátil que puedes usar File.separator en lugar de DIRECTORY_PATH_SEPARATOR.

2

Debe utilizar la clase File para esto, no una expresión regular.

Cuestiones relacionadas