正则表达式捕获最终子目录,无论它后面是否跟着终端斜杠字符?



我有一组目录路径名,可能如下所示:

foo/bar/baz

或者像这样,末尾加一个斜杠:

foo/bar/baz/

此外,目录路径可以是任意深度的 - 它不能保证只有3个级别,如我在这里所示;可能还有更多的级别。

我想写一个正则表达式来捕获最右边的子目录名称,无论呈现两种形式中的哪一种。

我可以为 grep 编写一个正则表达式'[^/]*$',它在第一种情况下可以正常工作:

> grep --version
grep (BSD grep) 2.5.1-FreeBSD
> echo "foo/bar/baz" | grep -o '[^/]*$'
baz
>

我怎样才能扩展它以纳入第二种情况? 似乎我需要在右侧(即"$"旁边(捕获 0 个或多个斜杠,但随后将它们扔掉,只匹配比这更左边的东西。 但是我不太清楚正确的语法。

您可以在 EOL 锚点之前添加一个可选/?$

/[^/]+(?=/?$)/

https://regex101.com/r/mHzLx0/1

解释

[^/]+                # Not forward slash char's
(?= /? $ )           # Lookahead, optional / then EOS

此外,目录路径可以是任意深度的 - 它不能保证只有 3 个级别,如我在这里所示; 可能还有更多级别。

您可以使用此awk

awk -F/ '{sub(//$/, ""); print $NF}' <<< "foo/bar/baz"
baz
awk -F/ '{sub(//$/, ""); print $NF}' <<< "foo/bar/baz/"
baz
awk -F/ '{sub(//$/, ""); print $NF}' <<< "abc/xyz/foo/bar/baz/"
baz

"转换"我的评论为答案:

使用sed的解决方案

sed -E 's@.*/([^/]+).*@1@'

-E(或-r,取决于操作系统(启用POSIX ERE语法。

图案详情

  • .*- 尽可能多地使用任何 0+ 字符,直到后续子模式最后一次出现
  • /-/符号
  • ([^/]+)- 第 1 组:除/以外的一个或多个字符
  • .*- 尽可能多地使用任何 0+ 字符,直到一行末尾。

更换部件中的1将存储在组 1 内存缓冲区中的内容复制回结果。

使用 GNUgrep的解决方案

如果您可以访问 PCRE 驱动的grep(例如 GNUgrep(,您可以使用

grep -oP '[^/]+(?=/?$)'

其中-o选项允许提取每个匹配项(而不是找到匹配项的行(,-P强制grep使用 PCRE 正则表达式引擎来解析模式。它启用环顾四周功能。Lookaround是非消耗模式,即它们匹配的文本不会添加到匹配值中,也不会推进正则表达式索引,因此,它们非常适合检查正则表达式中的各种条件。

图案详情

  • [^/]+- 一个否定的括号表达式,匹配任何字符,但/、1 次或更多次,最多
  • (?=/?$)- 行尾 ($( 的可选/(?量词匹配 1 或 0 次出现(。

这是最先进的PCRE正则表达式Web测试站点演示。

相关内容

最新更新