2010-11-01 12 views
5

Sto cercando di eseguire quanto segue in Java
fornire un percorso di directory come "https://stackoverflow.com/a/b/c" Voglio ottenere un array di stringhe come ["a", "b", "c"]. Il codice è il seguente:Java: espressione regolare per dividere i percorsi di directory

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

      String[] directories; 

     while(iter.hasNext()) { 

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

ma quello che ottengo come matrice è lo spazio pure. Voglio ottenere tutte quelle stringhe con length>0.
come posso farlo ??

risposta

4

L'unico posto in cui si ottiene una stringa vuota (in un percorso valido) sarebbe il primo elemento se il percorso è iniziato con il separatore. Se avesse il separatore principale, dividi il percorso senza di esso.

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

Come notato da OmnipotentEntity, la mia ipotesi era sbagliata su percorsi validi. Dovresti altrimenti passare attraverso l'array e mantenere stringhe non vuote quando usi 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); 

Un'alternativa è quella di utilizzare effettivamente le espressioni regolari per abbinare i caratteri non-separazione:

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

In realtà non è vero: "/ a // b ////// c" è anche un percorso valido. – OmnipotentEntity

+0

@Omni: È davvero un percorso valido? Se è così, dovrò rivedere. –

+0

Per vero. Provalo tu stesso in una shell. :) Probabilmente la cosa migliore da fare sarà percorrere l'array dopo averlo fatto ed eliminare le stringhe vuote. – OmnipotentEntity

0

Ecco una versione non-regex più affidabile che utilizza le routine di file system:

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

Codice di prova:

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

uscita:

[, casa, seanizer, progetti, eclissi, Helios2, stackfiddler, foo, bar, phleem.txt]

mi restituirà un elenco perché è più utilizzabile , ma non c'è niente che impedisca di uno cambiare il metodo per restituire un array o la conversione il risultato dall'esterno usando questo:

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

Il metodo String.split(String) non è molto flessibile e i suoi risultati possono essere sorprendenti (ad esempio, ignorando in silenzio le stringhe finali vuote). Sto usando il Guava libraries (Google Nucleo biblioteche per Java) per tutti i miei progetti, e che contiene una bella utility Splitter che fa quello che si desidera in un modo molto leggibile e prevedibile:

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

che ti dà un iterabile che è possibile utilizzare direttamente in un ciclo come questo:

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

in questo caso non ha nemmeno creare un oggetto intermedio per immagazzinare le directory, ma li crea al volo.

Se avete bisogno della lista di directory, è possibile copiare il iterabile in una ArrayList o un array come questo:

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

Come nota di chiusura: Per la scrittura di codice portabile si dovrebbe usare File.separator invece di DIRECTORY_PATH_SEPARATOR.

2

È necessario utilizzare la classe File per questo, non una regex.

Problemi correlati