2010-11-01 2 views
5

J'essaie de faire ce qui suit en Java
donne un chemin de répertoire comme "https://stackoverflow.com/a/b/c" Je veux obtenir un tableau de chaînes en tant que ["a", "b", "c"]. Le code est le suivant:Java - expression régulière pour diviser les chemins de répertoire

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

      String[] directories; 

     while(iter.hasNext()) { 

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

mais ce que j'obtiens en tant que tableau, c'est aussi de l'espace. Je veux obtenir toutes ces chaînes avec length>0.
comment puis-je faire ça ??

Répondre

4

Le seul endroit où vous obtiendriez une chaîne vide (dans un chemin valide) serait le premier élément si le chemin commençait par le séparateur. S'il avait le séparateur principal, diviser sur le chemin sans elle.

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

Comme l'a noté OmnipotentEntity, mon hypothèse était erronée sur les chemins valides. Sinon, vous devez parcourir le tableau et conserver les chaînes non vides lorsque vous utilisez 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); 

Une alternative est d'utiliser des expressions régulières réelles pour correspondre à des caractères non-séparateur:

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

En fait, ce n'est pas vrai: "/ a // b ////// c" est aussi un chemin valide. – OmnipotentEntity

+0

@Omni: Est-ce vraiment un chemin valide? Si oui, je vais devoir réviser. –

+0

Pour vrai. Essayez-le vous-même dans une coquille. :) Probablement la meilleure chose à faire sera marcher le tableau après que ce soit fait et éliminer les chaînes vides. – OmnipotentEntity

0

est ici une version non-regex plus fiable qui utilise des routines du système de fichiers:

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; 
} 

Code de l'essai:

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); 
} 

Sortie:

[, maison, seanizer, projets, éclipse, Helios2, stackfiddler, foo, bar, phleem.txt]

Je reviens d'une liste, car il est plus facile à utiliser , mais il n'y a rien pour vous empêcher de changer soit la méthode pour retourner un tableau ou la conversion du résultat de l'extérieur en utilisant celle-ci:

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

La méthode String.split(String) n'est pas très flexible, et ses résultats peuvent être surprenants (par exemple en rejetant silencieusement des chaînes de caractères vides). J'utilise le Guava libraries (Google de base des bibliothèques pour Java) pour tous mes projets, et qui contient une très belle Splitter utilitaire qui fait ce que vous voulez d'une manière très lisible et prévisible:

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

Cela vous donne une itérables que vous pouvez utiliser directement dans une boucle comme ceci:

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

dans ce cas, il ne crée même pas un objet intermédiaire pour stocker les répertoires, mais il les crée à la volée.

Si vous avez besoin la liste des répertoires, vous pouvez copier le itérables dans un ArrayList ou un tableau comme celui-ci:

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

Comme une note de clôture: Pour l'écriture de code portable, vous devez utiliser File.separator au lieu de DIRECTORY_PATH_SEPARATOR.

2

Vous devez utiliser la classe File pour cela, pas une regex.