Windows路径的正则表达式

6
作为 fortify 修复的一部分,我们需要验证文件路径。例如,
  1. "C:/Users/<username>/sample1.txt"
  2. "C:\Users\<username>\sample1.txt"
我们尝试使用以下正则表达式验证上述路径,但当文件路径包含 \ 时,我们遇到了错误。因此,请建议可以接受文件路径中两个斜杠的有效正则表达式。
Validator.FilePath=.*[\\]\\[!"#$%&'()_*+,/:;<=>?@\\^`{|}~].*

1
你只是想检查路径是否有效还是实际存在吗?在后一种情况下,我会创建一个新的“File”对象,并让框架处理路径转换。在前一种情况下,您可以执行类似的操作,但需要遍历父级层次结构并检查每个父级,直到满足某个条件为止。 - 或者您可以查看像Apache Commons IO这样的库,它通常具有与路径相关的实用程序。 - Thomas
你尝试过这样吗:.(/|\)。(\|/)[!"#$%&'()_+,/:;<=>?@\^`{|}~]. - Shekhar Khairnar
private ESAPIValidationUtils() { }public static String getValidFilePath(String reqParam) { String validFileName = ""; try { if (null != reqParam) { validFileName = ESAPI.validator().getValidInput("文件路径: ", reqParam, "FilePath", 256, true); } } catch (ValidationException ex) { Log.error("com.dextersystems.util.ESAPIValidationUtils", "getValidFilePath()", ex); } return validFileName; } - Ramya
4个回答

7

您可以尝试以下方法:

[a-zA-Z]:[\\\/](?:[a-zA-Z0-9]+[\\\/])*([a-zA-Z0-9]+\.txt)
  • [a-zA-Z]: 用于表示驱动器号和 :
  • [\\\/] 用于匹配 \/
  • (?:[a-zA-Z0-9]+[\\\/])* 用于文件夹名称。您可以在字符类中添加任何所需的字符。我只使用了 a-zA-Z0-9
  • ([a-zA-Z0-9]+\.txt) 用于文件名和 .txt 扩展名 - 它匹配文件名,带有扩展名,并对其进行捕获。

如何匹配文件夹名称和文件名中的空格Pattern pattern = Pattern.compile("[a-zA-Z]:\\/*([a-zA-Z0-9]+\.(xls|xlsx))",Pattern.CASE_INSENSITIVE);Matcher matcher = pattern.matcher("e:/avinash/testing file.xlsx"); Matcher matcher = pattern.matcher("e:/avinash testing/testing file.xlsx"); boolean matchFound = matcher.find(); 这不起作用。需要帮助。 - Avinash Reddy

4

就我个人而言,这是我多年来用来验证任何有效的Windows路径+文件的模式:

^
  (?<drive>[a-z]:)?
  (?<path>(?:[\\]?(?:[\w !#()-]+|[.]{1,2})+)*[\\])?
  (?<filename>(?:[.]?[\w !#()-]+)+)?[.]?
$

它可以适应有或无驱动器字母、可选的根标记、相对路径(“.”和“..”)以及文件和文件夹名称中的句点。此外,它还通过捕获组标签使提取信息变得简单/易于操作。唯一的注意事项是需要对路径名称中的双点进行二次检查。正则表达式101示例

看起来不错,但它没有涵盖相反的斜杠。 - Dariusz
@Dariusz -- 呃,那是因为正如开头所述,它最初是_严格用于验证_Windows_路径的,并且我不在意Windows最近添加了自动unix语法插值。不过,如果您觉得绝对需要为_Unix_路径添加支持,这是一个相当容易/明显/直接的修改... - NetXpert
不满足很多变化:例如文件名中允许出现“+”以及其他某些字符,同时允许多个连续的点等。 - Erik
“加号”符号是DOS 8.3文件名中的特殊字符(用于文件连接),它也是一系列不建议在文件名中使用的字符之一,这是最佳实践。同样地,允许连续的句点是路径误用的邀请,也违反了最佳实践,我完全不感兴趣允许其中任何一个。然而,如果您对最佳实践持中立态度,并且希望接受比我更多的字符,则模式很容易修改... - NetXpert
这个正则表达式无法处理这个文件路径: "C:\abc\folderone\foldertwo\test\my.subfolder\another_subfolder\Filename.AlphaBetaGamma.txt"找到了解决问题的线索: https://stackoverflow.com/questions/3525919/regex-problem-ismatch-method-never-returns总是陷入无限循环中。(.NET RegEx类) - Marcus.D
@MarcusD -- 好的,虽然我不确定 .NET 类代码本身的明显缺陷/错误如何成为我的责任,也不知道这个问题如何使此模式的适用性无效... ‍♀️ - NetXpert

1

这是我的解决方案:

^(?i)\s*([a-z]:/?)?(?:[^?*:;|<>\r\n\\]*)(/\1*|\1*)(.\1*)*[^.]$

满足:

c:
c:/
c:notepad++
c:/notepad++
notepad
C:/not epad++/notepad++/notepad++.exe.txt.xaml
C:notepad++/notepad++/notepad++.exe.txt.xaml
C:notepad++//notepad++/notepad++...exe.txt.xaml
C:notepad++/notepad++
.xaml
 c:notepad++/
 C:/notepad++/notepad++/
 C:/notepad++/notepad++/a
 C:/notep ad++/notepad++

但不是:

C:notepad++/notepad++/notepad++.exe.txt.

1
为什么需要自引用组?这个表达式也会匹配例如 someone@example.com/\/\/\ 和一个换行符。 - Scratte
正如所写,此处缺少两个转义符(Regex101:[链接](https://regex101.com/r/D01d3B/1));修复后,它不会为驱动器、路径或文件名提供捕获组,并且在您提供的每个示例中都创建空/ null捕获组。 它还接受冒号和斜杠模式中的任何位置,包括将字符串“:::::::::::::::::::”和“\\\\\\\\\\”作为有效路径+文件名传递。 不应接受开头或结尾处的空格,但是这两者都允许。 实际上,我实际上找不到此模式会拒绝的字符串。 - NetXpert
1
我站在纠正的一边:实际上,任何以句点结尾的字符串都会失败,即使在Windows文件名中具有结尾句点也是可以接受的... 这种模式显然还验证了星号和问号(即通配符字符),大于、小于和管道字符(即重定向)以及文件名中间的双引号/单引号/反斜杠。例如,它显然认为 >::"woops!"*?<| 是一个有效的Windows文件名。 - NetXpert
奇怪的是,在资源管理器中创建一个名为>::"woops!"*?<|的文件非常顺利。只是,它会被资源管理器自动更改为woops!那么:这是有效的还是无效的? - Erik
确实,我在使用正则表达式时太过草率了。 但我学到了一些东西: 1:正则表达式是一个蛇窝。 2:需要回答的第一个问题是:我是否需要正则表达式?在我的情况下:我意识到我不需要检查文件名的有效性,而是需要检查程序是否能找到该文件(File.Exists(.....))。 3:并非总是需要为文件名找到通用的正则表达式。许多用例需要特殊的正则表达式。 4:"有效文件名"的含义并不总是清晰明确。 - Erik

-1
Validator.FilePath=(?:[a-zA-Z]\\:|[\\\\\\\\|/]+[\\w\\.]+)[\\\\|/]?([\\w]+[\\\\|/])*[\\w]*(\\.\\w+)$

1
请尽量解释一下您的解决方案。 - Anirudh Sharma
如上所述,它未能通过我的任何测试。 - Erik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接