Regex 如何使正则表达式与文件路径匹配?
我已经用这个命令玩了一两个小时了,恐怕我已经失去了客观性目标是只匹配提供给bash的相对文件路径。 第一个相对路径Regex 如何使正则表达式与文件路径匹配?,regex,bash,grep,Regex,Bash,Grep,我已经用这个命令玩了一两个小时了,恐怕我已经失去了客观性目标是只匹配提供给bash的相对文件路径。 第一个相对路径或/some/file/path 第二个相对路径是。或。/some/file/path 其中“/some/file/path”的长度是任意的 我一直在使用bash中的grep试图找出如何在我的脚本中实现它,这样我就可以将它扩展到它的绝对文件路径,从而/some/file/path或。/some/file/path变成/the/absolute/file/path;我已经弄明白了 我的
或/some/file/path
第二个相对路径是。
或。/some/file/path
其中“/some/file/path”的长度是任意的
我一直在使用bash
中的grep
试图找出如何在我的脚本中实现它,这样我就可以将它扩展到它的绝对文件路径,从而/some/file/path
或。/some/file/path
变成/the/absolute/file/path
;我已经弄明白了
我的问题是匹配相对路径。
我一直使用的代码是
echo "../some/file/path" | egrep '\.{1}/?[[:graph:]]?+$'
及
我把我的问题缩小到
echo ".." | egrep '\.{2}'
只要点出现了2+n
次,就会与点匹配,不完全是预期的2次出现。当我将其更改为
echo ".." | egrep '\.{1}'
由于某种原因,我想不出是否会匹配
最终的实现应该是这样工作的
41 _expand_relative_path () {
42 if [[ "$1" =~ ^\.{1}/?[[:graph:]]?+$ ]]; then
43 echo "."
44 elif [[ "$1" =~ ^\.{2}/?[[:graph:]]?+$ ]]; then
45 echo ".."
46 else
47 echo "$1"
48 fi
49 }
根据我的课本,如果说明符{n}恰好出现n次,它将与前面的元素匹配。但它不会那样做!如果是n次或更多次,则匹配!我做错了什么?匹配相对路径的正则表达式不是以斜杠开头的:
^[^/].*
^\.{1}/?[[:graph:][]?+$
的问题是,/
已被指定为可选,以下[[:graph:][]
字符类与任何可见字符匹配,包括更多句点。另外,你已经用?+
量化了你的角色类,意思是“零或一次,占有”:它不必匹配,但如果匹配,它不会“放弃”匹配的内容,让其他模式尝试成功-可能不是你想要的
当你说echo..“|egrep'\.{2}'
时,你所说的是“字符串在某个点上包含一行两个句点”-但这并不意味着它不能有更多的句点或其他任何东西,不管怎样,没有^
和$
锚定,这将限制为精确且只有两个句点
正如其他人所注意到的,任何不以/
开头的路径都是相对的,因此^[^/].
可以工作。但是,如果要查找文本文件中包含其他文本的相对路径,这可能很有用:
(\.{1,2}(?:\/[[:alnum:]]*)*)
输出:
将匹配点,只要它有2+n个引用,而不是正好2个
如预期的那样
嗯,是的。默认情况下,grep
打印包含图案的行。任何包含两个以上连续点的线都必须包含两个连续点,因此图案匹配
当我将其更改为
echo ".." | egrep '\.{1}'
由于某种原因,我想不出是否会匹配
同样的事情:字符串“.”包含一个“.”,因此它与模式匹配
现在,考虑一下您的原始模式,'\.{2}/?[[:graph:]?+$'
:
/foo/bar../baz
(和其他)的绝对路径。在模式中需要一个初始的^
来锚定它?
量词,可以选择在前导点后出现/
。如果您的目标是专门匹配第一段为的路径,则不清楚为什么要这样做。
。我能想到的唯一一件事是,您希望匹配路径,该路径恰好是。
本身,您的模式确实如此,但它太容易接受[[:graph:][]?+
,这似乎是编写更标准的[[:graph:][]*
的一种奇怪的方式。此外,您似乎依赖于这样一个事实,即[[:graph:]
将匹配它将匹配的/
字符,因此您最好将前面的可选/
直接滚动到character类中:'^\.{2}[:graph:]*$'
[[:graph:]
也匹配
。现在,这解释了为什么原始模式匹配包含两个以上连续点的字符串:前两个由\.{2}
匹配,没有任何内容由/?
匹配,其余的点(可能还有其他字符)由[[:graph:][]匹配
或。
的路径,包括那些没有其他段,并且没有尾随的//code>的路径,那么您可以尝试以下方法:
egrep '^\.{1,2}(/.*[^/])?$'
- 它被锚定在开头(
^
)和结尾($
),因此它只执行整行匹配
- 匹配行必须以一个或两个点开始(
\.{1,2}
)
- 其他任何内容都是可选的(
(…)?
),但如果存在该可选段,则它必须以/
开头,并以非/
的字符结尾。中间可以是任何字符的任何数字,包括零(*
)
- 请注意,Unix文件名和目录名可以包含空格和非图形字符,因此在原始模式中使用
[:graph://code>将其限制为可能路径的子集
适用于Windows:^.\\\(?!.\\)(.*)$
或者对于Linux:^.*/(?!.*/)(.*)$
或两者皆适用:
^.*(:\\\\\\/)(?!.*(:\\\\\\\/)(*))
echo ".." | egrep '\.{1}'
egrep '^\.{1,2}(/.*[^/])?$'