Java - регулярное выражение для разделения путей к каталогам - PullRequest
5 голосов
/ 01 ноября 2010

Я пытаюсь сделать следующее в Java
указать путь к каталогу, например "/a/b/c" Я хочу получить массив строк как ["a", "b", "c"].Код выглядит следующим образом:

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

            String[] directories;

        while( iter.hasNext() ) {

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

, но в качестве массива я получаю также пространство.Я хочу получить все эти строки с length>0.
как я могу это сделать ??

Ответы [ 4 ]

4 голосов
/ 01 ноября 2010

Единственное место, где вы получите пустую строку (в допустимом пути), будет первым элементом, если путь начинается с разделителя.Если в нем был ведущий разделитель, разделенный на пути без него.

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

Как отметил OmnipotentEntity, мое предположение было неверным в отношении допустимых путей.В противном случае вам придется проходить через массив и сохранять непустые строки при использовании split().

String path = "/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);

Альтернативой является использование фактических регулярных выражений для сопоставления с символами, не являющимися разделителями:

String path = "/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());
3 голосов
/ 01 ноября 2010

Для этого вы должны использовать класс File, а не регулярное выражение.

1 голос
/ 01 ноября 2010

Метод String.split(String) не очень гибок, и его результаты могут быть удивительными (например, молча отбрасывать пустые конечные строки).Я использую библиотеки Guava (Google Core Libraries для Java) для всех своих проектов, и в них содержится очень хорошая утилита Splitter, которая делает то, что вы хотите, в очень удобочитаемоми предсказуемым образом:

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

Это дает вам итерацию, которую вы можете напрямую использовать в цикле for следующим образом:

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

В этом случае он даже не создает промежуточногообъект для хранения каталогов, но он создает их на лету.

Если вам нужен список каталогов, вы можете скопировать итерируемое в ArrayList или массив, например так:

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

В качестве заключительного замечания: для написания переносимого кода вы должны использовать File.separator вместо DIRECTORY_PATH_SEPARATOR.

0 голосов
/ 01 ноября 2010

Вот более надежная версия без регулярных выражений, в которой используются процедуры файловой системы:

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

Тестовый код:

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

Вывод:

[, home, seanizer, проекты, eclipse, helios2, stackfiddler, foo, bar, phleem.txt]

Я возвращаю список, потому что он более пригоден для использования, но ничто не мешает вам либо изменить метод для возврата массива, либо преобразовать результат извне, используя это:

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