用于解析目录和文件名的正则表达式

时间:2008-10-03 21:41:08

标签: regex parsing

我正在尝试编写一个正则表达式,它将使用匹配组解析完全限定路径的目录和文件名

所以...

/var/log/xyz/10032008.log

会识别group 1 to be "/var/log/xyz"group 2 to be "10032008.log"

看起来很简单,但我不能让匹配的小组为我的生活工作。

注意:正如一些受访者所指出的,这可能不是正常表达的好用。通常我更喜欢使用我正在使用的语言的文件API。我实际上要做的事情比这更复杂但是要解释起来要困难得多,所以我选择了一个每个人都熟悉的域名,以便最简洁地描述根本问题。

9 个答案:

答案 0 :(得分:30)

试试这个:

^(.+)/([^/]+)$

答案 1 :(得分:16)

支持使用non-capturing groups的正则表达式的语言:

((?:[^/]*/)*)(.*)

我将通过爆炸来解释这个粗糙的正则表达式......

(
  (?:
    [^/]*
    /
  )
  *
)
(.*)

这些部分意味着什么:

(  -- capture group 1 starts
  (?:  -- non-capturing group starts
    [^/]*  -- greedily match as many non-directory separators as possible
    /  -- match a single directory-separator character
  )  -- non-capturing group ends
  *  -- repeat the non-capturing group zero-or-more times
)  -- capture group 1 ends
(.*)  -- capture all remaining characters in group 2

实施例

为了测试正则表达式,我使用了以下Perl脚本......

#!/usr/bin/perl -w

use strict;
use warnings;

sub test {
  my $str = shift;
  my $testname = shift;

  $str =~ m#((?:[^/]*/)*)(.*)#;

  print "$str -- $testname\n";
  print "  1: $1\n";
  print "  2: $2\n\n";
}

test('/var/log/xyz/10032008.log', 'absolute path');
test('var/log/xyz/10032008.log', 'relative path');
test('10032008.log', 'filename-only');
test('/10032008.log', 'file directly under root');

脚本的输出......

/var/log/xyz/10032008.log -- absolute path
  1: /var/log/xyz/
  2: 10032008.log

var/log/xyz/10032008.log -- relative path
  1: var/log/xyz/
  2: 10032008.log

10032008.log -- filename-only
  1:
  2: 10032008.log

/10032008.log -- file directly under root
  1: /
  2: 10032008.log

答案 2 :(得分:8)

大多数语言都有路径解析功能,这些功能已经为您提供了这些功能。如果你有这种能力,我建议你免费使用免费提供给你的东西。

假设/是路径分隔符......

^(.*/)([^/]*)$

第一组将是目录/路径信息,第二组将是文件名。例如:

  • /foo/bar/baz.log :“/ foo / bar /”是路径,“baz.log”是文件
  • foo / bar.log :“foo /”是路径,“bar.log”是文件
  • / foo / bar :“/ foo /”是路径,“bar”是文件
  • / foo / bar / :“/ foo / bar /”是路径,没有文件。

答案 3 :(得分:4)

用什么语言?为什么要使用正则表达式完成这个简单的任务?

如果必须

^(.*)/([^/]*)$

为您提供您想要的两个部分。您可能需要引用括号:

^\(.*\)/\([^/]*\)$

取决于您的首选语言语法。

但我建议你只使用你的语言的字符串搜索功能找到最后一个“/”字符,然后在该索引上拆分字符串。

答案 4 :(得分:1)

这个怎么样?

[/]{0,1}([^/]+[/])*([^/]*)

确定性:

((/)|())([^/]+/)*([^/]*)

严格:

^[/]{0,1}([^/]+[/])*([^/]*)$
^((/)|())([^/]+/)*([^/]*)$

答案 5 :(得分:0)

试试这个:

/^(\/([^/]+\/)*)(.*)$/

但是它会在路径上留下尾部斜杠。

答案 6 :(得分:0)

答案非常晚,但希望这会有所帮助

^(.+?)/([\w]+\.log)$

这使用/的延迟检查,我刚修改了接受的答案

http://regex101.com/r/gV2xB7/1

答案 7 :(得分:0)

原因:

我通过反复试验方法进行了一些研究。发现* nux机器中键盘上所有可用的值都可以作为文件或目录,但'/'除外。

我使用touch命令为后面的字符创建文件,并创建了一个文件。

  

(下面用逗号分隔的值)
  '!','@','#','$',“''','%','^','&','*','(',')','','''' ,'\','-',',','[',']','{','}','`','〜','>','<','=',' +',';',':','|'

仅当我尝试创建'/'(因为它是根目录)和文件名容器/时,它失败了,因为它是文件分隔符。

当我执行.时,它更改了当前目录touch .的修改时间。但是,可以使用file.log。

当然,a-zA-Z0-9-(连字符),_(下划线)应该可以工作。

结果

因此,根据上述推理,我们知道文件名或目录名可以包含除/前斜杠之外的任何内容。因此,我们的正则表达式将由文件名/目录名中不存在的内容派生。

/(?:(?P<dir>(?:[/]?)(?:[^\/]+/)+)(?P<filename>[^/]+))/

分步正则表达式创建过程

模式说明

步骤1:从匹配的root目录开始

如果目录是绝对路径,则目录可以以/开头,而相对目录则可以以目录名开头。因此,请寻找出现次数为零或一次的/

/(?P<filepath>(?P<root>[/]?)(?P<rest_of_the_path>.+))/

enter image description here

步骤2:尝试找到第一个目录。

接下来,目录及其子目录始终由/分隔。目录名称可以是/以外的任何名称。我们先匹配/ var/。

/(?P<filepath>(?P<first_directory>(?P<root>[/]?)[^\/]+/)(?P<rest_of_the_path>.+))/

enter image description here

第3步:获取文件的完整目录路径

接下来,让我们匹配所有目录

/(?P<filepath>(?P<dir>(?P<root>[/]?)(?P<single_dir>[^\/]+/)+)(?P<rest_of_the_path>.+))/

enter image description here

在这里,single_dir为yz/,因为首先匹配var/,然后找到下一个相同模式的出现,即log/,然后发现下一个相同模式的{{1 }}。因此,它显示了模式的最后一次出现。

步骤4:匹配文件名并清理

现在,我们知道我们永远不会使用诸如single_dir,filepath,root之类的组。因此,让我们清理一下。

让我们将它们分组,但是不要捕获这些分组。

rest_of_the_path只是文件名!因此,将其重命名。而且文件名中不会包含yz/,因此最好保留/

[^/]

这使我们得到最终结果。当然,还有其他几种方法可以执行此操作。我只是在这里提到一种方法。

enter image description here

上面使用的正则表达式规则在此处列出

/(?:(?P<dir>(?:[/]?)(?:[^\/]+/)+)(?P<filename>[^/]+))/ 表示字符串以
开头 ^表示按组名称捕获组。我们有两个组,组名分别为(?P<dir>pattern)dir
file表示不考虑此组或不捕获该组。
(?:pattern)表示匹配零或一。 ?表示匹配一个或多个 +表示匹配除正斜杠([^\/])以外的任何字符

/表示如果它是绝对路径,则可以以/开头,否则就不能。因此,请匹配[/]?的零个或一个匹配项。

/表示一个或多个不是正斜杠([^\/]+/)的字符,其后是正斜杠(/)。这将匹配/var/。一次一个目录。

答案 8 :(得分:0)

以上传文件夹 URL 为例:

https://drive.google.com/drive/folders/14Q6d-KiwgTKE-qm5EOZvHeX86-Wf9Q5f?usp=sharing

正则表达式模式为:

[-\w]{25,}   

此模式也适用于 Google 表格以及 Excel 中的自定义函数:

=REGEXEXTRACT(N2,"[-\w]{25,}")

结果是:14Q6d-KiwgTKE-qm5EOZvHeX86-Wf9Q5f

enter image description here

enter image description here

enter image description here