1. 概述

在Java中操作文件系统时,验证文件夹路径至关重要,这能确保应用程序正确且安全地运行。使用正则表达式(regex)是执行路径验证的高效方法之一。

本教程将探讨如何在Java中使用正则表达式验证Linux文件夹路径,确保我们使用的路径符合预期的模式和规范。

2. 问题引入

在应用中实现Linux目录路径时,我们通常需要遵循特定要求,而不是接受特定Linux文件系统(如ext4)的所有有效路径。

例如,假设应用中的Linux目录字符串必须满足以下条件:

  • ✅ 目录路径不能为空
  • ✅ 路径必须是绝对路径(以斜杠/开头),不允许使用./foo../foo这类相对路径
  • ✅ 除斜杠外,绝对路径只能包含连字符-、下划线_、数字以及大小写字母
  • ✅ 目录路径不能以斜杠结尾(例如/foo/bar/无效),但有一个例外:根目录/是允许的

⚠️ 需要注意:我们的验证目的不是检查给定目录路径在当前文件系统中是否存在。如果需要检查文件或目录是否存在,正则表达式可能不是合适的工具。

接下来,让我们看看如何构建满足这些验证规则的正则表达式模式。

3. 构建正则表达式模式

乍一看,创建满足所有要求的正则表达式可能很复杂。但别担心,我们一步步来构建,会发现这其实并不难。

首先,由于有效路径总是以斜杠开头,且只允许连字符-、下划线_、数字和字母,我们可以先创建这个基础模式:^/[0-9a-zA-Z_-]+$。字符类[0-9a-zA-Z_-]匹配单词字符。在正则表达式中,\w是单词字符类的简写形式。因此,我们可以用\w替换0-9a-zA-Z_-,使模式更简洁易读:^/[\w-]+$

当前模式只能匹配顶级目录(如/foo/123)。但目录可能包含多级子目录,例如/foo/sub1/sub2/sub3

仔细分析这个路径会发现:包含子目录的有效路径由多个目录字符串组成。例如/foo/sub1/sub2/sub3包含四个符合顶级目录模式的片段:/foo/sub1/sub2/sub3

因此,为了匹配连续的多级目录,我们可以将顶级目录模式放入捕获组,并对组使用+量词^(/[\w-]+)+$

这个模式几乎能匹配所有目录路径。但还有一个特殊情况未覆盖:根目录/。匹配/的模式是^/$我们可以使用"或"运算符|合并这两个模式^/$|^(/[\w-]+)+$

接下来测试这个模式是否符合预期:

AssertJ库允许我们在测试中编写流畅的断言语句,并提供了许多便捷方法验证测试结果。例如,我们可以使用其matches()doesNotMatch()方法验证正则表达式匹配:

String regex = "^/$|^(/[\w-]+)+$";
assertThat("/").matches(regex);
assertThat("/foo").matches(regex);
assertThat("/foo/0").matches(regex);
assertThat("/foo/0/bar").matches(regex);
assertThat("/f_o_o/-/bar").matches(regex);
 
assertThat("").doesNotMatch(regex);
assertThat("  ").doesNotMatch(regex);
assertThat("foo").doesNotMatch(regex);
assertThat("/foo/").doesNotMatch(regex);
assertThat("/foo/bar/").doesNotMatch(regex);
assertThat("/fo o/bar").doesNotMatch(regex);
assertThat("/foo/b@ar").doesNotMatch(regex);

如测试所示,我们的正则表达式通过了所有正向和反向测试。因此,使用该模式的验证器完全满足需求。

4. 总结

在Java中使用正则表达式验证Linux文件夹路径是一种强大的技术,能确保路径符合预期模式。

通过本文介绍的技术,我们可以在Java项目中自信地处理Linux路径,编写出更健壮、更易维护的代码。

一如既往,所有示例的完整源代码可在GitHub上获取。


原始标题:Validating Linux Folder Paths using Regex in Java | Baeldung