【问题标题】:Java - regular expression to split directory pathsJava - 用于拆分目录路径的正则表达式
【发布时间】:2010-11-01 06:08:41
【问题描述】:

我正在尝试在 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 获取所有这些字符串。
我怎样才能做到这一点??

【问题讨论】:

    标签: java regex split


    【解决方案1】:

    如果路径以分隔符开头,则唯一会得到空字符串(在有效路径中)的地方是第一项。如果它有前导分隔符,则在没有它的路径上拆分。

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

    【讨论】:

    • 其实不正确:“/a//b/////c”也是有效路径。
    • @Omni:这真的是一条有效的路径吗?如果是这样,我将不得不修改。
    • 正确。在 shell 中自己尝试一下。 :) 可能最好的办法是在完成后遍历数组并消除空字符串。
    • @Omni:感谢您的提醒。我不知道。
    【解决方案2】:

    您应该为此使用 File 类,而不是正则表达式。

    【讨论】:

      【解决方案3】:

      String.split(String) 方法不是很灵活,它的结果可能令人惊讶(例如默默地丢弃空的尾随字符串)。我的所有项目都使用Guava libraries(Google Core Libraries for 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

      【讨论】:

        【解决方案4】:

        这是一个使用文件系统例程的更可靠的非正则表达式版本:

        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, projects, eclipse, helios2, stackfiddler, foo, bar, phleem.txt]

        我返回一个 List 是因为它更有用,但没有什么可以阻止您更改返回数组的方法或使用此方法从外部转换结果:

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

        【讨论】:

          猜你喜欢
          • 2023-02-08
          • 2021-06-17
          • 1970-01-01
          • 2021-12-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-09
          • 1970-01-01
          相关资源
          最近更新 更多