【问题标题】:What is the most correct regular expression for a UNIX file path?UNIX 文件路径最正确的正则表达式是什么?
【发布时间】:2009-02-11 16:57:53
【问题描述】:

对于 UNIX 文件路径,最正确的正则表达式 (regex) 是什么?

例如,要检测这样的事情:

/usr/lib/libgccpp.so.1.0.2

创建一个匹配大多数文件的正则表达式非常容易,但最好的一个是什么,包括可以检测转义的空白序列和在 UNIX 上的文件路径中通常找不到的异常字符。

另外,是否有几种不同的编程语言提供文件路径正则表达式的库函数?

【问题讨论】:

  • “转义的空白序列”?使用什么转义语法? UNIX 路径没有这样的转义。 sh/ksh/bash 有一种最常见的转义语法,URL 有另一种,Perl 有另一种。

标签: regex path


【解决方案1】:

如果您不介意识别路径的误报,那么您真的只需要确保路径不包含NUL 字符;其他所有内容都是允许的(特别是,/ 是名称分隔符)。更好的方法是使用适当的文件 IO 函数(例如 Java 中的File.exists()File.getCanonicalFile())解析给定的路径。

长答案:

这取决于 operating systemfile system。例如,Wikipedia comparison of file systems 指出,除了文件系统施加的限制之外,

MS-DOS、Microsoft Windows 和 OS/2 禁止使用字符 \ / : ? * " > < |NUL 在文件和目录中 所有文件系统的名称。独联体 和 Linux 不允许字符 /NUL 在文件和目录名称中 跨所有文件系统

在 Windows 中,以下 reserved device names 也不允许作为文件名:

CON, PRN, AUX, NUL, COM1, COM2, COM3, COM4, COM5,
COM6, COM7, COM8, COM9, LPT1, LPT2, LPT3, LPT4, 
LPT5, LPT6, LPT7, LPT8, LPT9

【讨论】:

  • 附加:由于文件系统之间的多样性,有一些方法可以为您提供所需的信息。
  • 那些Win专用设备比你想象的还要糟糕。我曾经将 C 头文件从 const.h 重命名为 con.h,编译器似乎挂起。花了一段时间才发现它正在从控制台读取头文件,因为 Win 忽略了扩展名。警告:这可能是 DOS,这是很久以前的事了。
  • 有用的信息,但我不明白为什么这个不回答被接受...?
【解决方案2】:

匹配所有 UNIX 路径的正确正则表达式是:[^\0]+

即一个或多个非 NUL 字符。

【讨论】:

  • 和 '//' 是有效路径,有或没有 ''s
【解决方案3】:

对于已回答此问题的其他人,请务必注意,某些应用程序需要稍微不同的正则表达式,具体取决于您正在编写的程序中转义字符的工作方式。例如,如果您正在编写一个 shell,并且想要用空格和其他特殊字符分隔命令,您将不得不修改您的正则表达式,使其仅包含带有特殊字符的单词(如果这些字符被转义)。

因此,例如,一个有效的路径是

 /usr/bin/program\ with\空格

相对

 /usr/bin/program 有空格

这将引用带有参数“with”和“space”的“/usr/bin/program”

上面例子的正则表达式可以是 "([^\0 ]\|\\ )*"

我一直在处理的正则表达式是(为“可读性”而分隔换行符):

 "\( # 要么
       [^\0 !$`&*()+] # 一个普通(非特殊)字符
     \| # 或者
       \\\(\ |\!|\$|\`|\&|\*|\(|\)|\+\) # 转义的特殊字符
   \)\+" # 重复 >= 1 次

翻译成

"\([^\0 !$`&*()+]\|\\\(\ |\!|\$|\`|\&|\*|\(|\)|\+\)\ )\+"

创建您自己的特定正则表达式也应该相对简单。

【讨论】:

  • 作为枚举所有转义字符的替代方法,您可以简单地创建一个组,该组由转义字符后跟转义字符类([^ !$`&*()+]|(\\[ !$`&*()+]))+
【解决方案4】:
^(/)?([^/\0]+(/)?)+$

这将接受文件系统中所有合法的路径,例如 extXreiserfs

它只丢弃包含 NUL 或双(或更多)斜杠的路径名。根据 Unix 规范,其他一切都应该是合法的(我也对这个结果感到惊讶)。

【讨论】:

  • 双斜杠在unix路径中非常好,无论是在POSIX中还是在实践中,所以你的正则表达式不正确。 unix 路径名中唯一不允许的字符(或者更确切地说,八位字节)是 \0
  • @RememberMonica 你是说/var///test/file.txt 这样的路径有效吗?
  • @Slbox 是的,这是一个完全有效的文件路径。 /var///test/file.txt/var/test/file.txt 是等价的。这种约定使一些文件路径操作更简单。例如。 userProvidedPath + "/filename.txt" 无论userProvidedPath 是否包含尾部斜杠都有效。
  • 请注意,如果输入字符串包含多个相互连接的正斜杠,则此正则表达式的变体已被证明对我们来说很容易受到灾难性回溯的影响,至少在嵌入 Ruby 的 Oniguruma 上是这样。需要记住的一点。
【解决方案5】:

我不确定跨系统的正则表达式检查有多普遍,但大多数编程语言(尤其是跨平台语言)都提供“文件存在”检查,会考虑到这种情况

出于好奇,这些路径是在哪里输入的?您能否将其控制到更大程度,以至于您不必检查路径的各个部分?例如使用文件选择器对话框?

【讨论】:

    【解决方案6】:

    这里已经回答了问题:https://stackoverflow.com/a/42036026/1951947

    【讨论】:

      猜你喜欢
      • 2013-04-07
      • 1970-01-01
      • 2019-07-03
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多