推理:
我通过试错法做了一些研究。发现键盘中可用的所有值都可以作为文件或目录,除了 *nux 机器中的“/”。
我使用 touch 命令为以下字符创建文件,它创建了一个文件。
(下面的逗号分隔值)
'!'、'@'、'#'、'$'、"'"、'%'、'^'、'&'、'*'、'('、')'、 ' ', '"', '\', '-', ',', '[', ']', '{', '}', '`', '~', '>', '<' , '=', '+', ';', ':', '|'
仅当我尝试创建“/”(因为它是根目录)和文件名容器时它才失败,/
因为它是文件分隔符。
.
当我这样做时,它改变了当前目录的修改时间touch .
。但是,file.log 是可能的。
当然,a-z
, A-Z
, 0-9
, -
(hypen), _
(underscore) 应该可以工作。
结果
因此,通过上述推理,我们知道文件名或目录名可以包含除/
正斜杠之外的任何内容。因此,我们的正则表达式将由文件名/目录名中不存在的内容派生。
/(?:(?P<dir>(?:[/]?)(?:[^\/]+/)+)(?P<filename>[^/]+))/
一步一步的正则表达式创建过程
模式说明
步骤 1:从匹配root
目录开始
/
目录可以以绝对路径开头,目录名可以以相对路径开头。因此,寻找/
零次或一次出现。
/(?P<filepath>(?P<root>[/]?)(?P<rest_of_the_path>.+))/
步骤2:尝试找到第一个目录。
接下来,一个目录和它的子目录总是用 . 分隔/
。目录名称可以是除/
. 让我们先匹配/var/。
/(?P<filepath>(?P<first_directory>(?P<root>[/]?)[^\/]+/)(?P<rest_of_the_path>.+))/
步骤 3:获取文件的完整目录路径
接下来,让我们匹配所有目录
/(?P<filepath>(?P<dir>(?P<root>[/]?)(?P<single_dir>[^\/]+/)+)(?P<rest_of_the_path>.+))/
在这里, single_dir 是yz/
因为,首先它匹配var/
,然后它找到下一次出现的相同模式,即log/
,然后它找到下一次出现的相同模式yz/
。因此,它显示了模式的最后一次出现。
第 4 步:匹配文件名并清理
现在,我们知道我们永远不会使用像 single_dir、filepath、root 这样的组。因此,让我们清理一下。
让我们将它们保留为组,但不要捕获这些组。
而 rest_of_the_path 只是文件名!所以,重命名。而且文件的名称中不会有/
,所以最好保留[^/]
/(?:(?P<dir>(?:[/]?)(?:[^\/]+/)+)(?P<filename>[^/]+))/
这给我们带来了最终的结果。当然,还有其他几种方法可以做到。我只是在这里提到一种方式。
上面使用的正则表达式规则在此处列出
^
表示以组名开头的字符串
(?P<dir>pattern)
表示捕获组。我们有两个带有组名的组dir
,file
(?:pattern)
意味着不考虑这个组或非捕获组。
?
表示匹配零或一。
+
表示匹配一个或多个
[^\/]
表示匹配除正斜杠 ( /
)之外的任何字符
[/]?
意味着如果它是绝对路径,那么它可以以 / 开头,否则它不会。因此,匹配零个或一个/
.
[^\/]+/
表示一个或多个不是正斜杠 ( /
) 后跟正斜杠 ( ) 的字符/
。这将匹配var/
或xyz/
。一次一个目录。