我想匹配第一个和最后一个斜杠/
之间的所有内容,包括第一个斜杠之前的可选~
。
我在第一部分使用了这个:
echo ~~a~/dir1/di r2/b.c
| perl -pe 's/[^/]*(/.*/).*/1/'
从而产生CCD_ 3。
此匹配包括波浪号:
perl -pe 's/
.*(
~/.*/).*/1/'
但是为可选字符添加?
似乎不像在这些情况下那样工作:
perl -pe 's/
.*(
~/.*/).*/1/'
->/di r2/
perl -pe 's/
.*(
(?:~)/.*/).*/1/'
->~~a/dir1/di r2/b.c
我做错了什么?
如果我正确理解所需的输出,无论是否使用波浪号,这都适用于我
echo "path /d1/d2/43a/" | perl -nE 'm{ ( ~? (?: /.*/ | /) ) }x; say "$1"'
打印
/d1/d2/43a/
相同的Perl代码,在输入的第一个斜杠之前有一个波浪号
echo "path ~/d1/d2/43a/" | perl -nE 'm{ ( ~? (?: /.*/ | /) ) }x; say "$1"'
打印
~/d1/d2/43a/
备注;不赞成在替换中使用/1
。请改用$1
。使用{}
作为分隔符,我们不必转义/
,使其更具可读性(而使用除//
之外的分隔符,则不能在前面省略m
)。否则,当使用/
作为分隔符,然后在内部对其进行转义时,情况也是如此。
更新
为了捕获一个单独的~/
(或/
),最简单的更改是显式添加/.*/ | /
。为了在这两种情况下捕获(光学的)~
,围绕这一点有一个(非捕获的)分组。删除了-w
标志,因此当输入字符串根本没有斜杠,但只打印空行时,不会发出警告。
原始要求
文件data
~~a~/dir1/di r2/b.c
/dir1/di r2/z.y
~/dir1/di r3/p.q
gobbledegook~/name/more/still/more/notwanted.c
xxx~//yyy
脚本
perl -ple 's%(?:^.*?)((?:^|~)/.*/).*%$1%' data
示例输出
~/dir1/di r2/
/dir1/di r2/
~/dir1/di r3/
~/name/more/still/more/
~//
这就是你需要的吗?
解析正则表达式
s%(?:^.*?)((?:^|~)/.*/).*%$1%
第一部分(?:^.*?)
是一个非捕获的非贪婪匹配,用于行首的任意字符序列。
第二部分/dir1/di r2/
0是一个捕获表达式,它包含一个非捕获项,该项在一行的开头匹配,或波浪号,后跟一个斜杠和一个贪婪的任意值,直到该行的最后一个斜杠。
后面的.*
匹配第二部分之后的所有内容。
替代品只是被捕获的东西;剩下的就是Perl就是Perl。
修订后的要求
最初的问题陈述似乎不完整。显然:
对于单斜线,它应该只输出
/
(如果存在,则附带波浪号)。对于无斜杠,最好是空字符串,因为没有匹配…对于这种情况~a b/c/d.f
,它返回完整的字符串;而是应该返回CCD_ 34。
所以,这里有一个修改后的脚本来处理特殊的额外情况("学习如何钓鱼"发生了什么?)。~a b/c/d.f
大小写是"字符串或波浪号开头"分组中缺少的?
限定符。
修订data
文件
~~a~/dir1/di r2/b.c
/dir1/di r2/z.y
~/dir1/di r3/p.q
gobbledegook~/name/more/still/more/notwanted.c
xxx~//yyy
not-a-slash-in-sight
just-the-one/with-extra-info
just-the~/with-more-info
~/one-slash-at-start-with-tilde
/one-slash-at-start-without-tilde
~a b/c/d.f
修改后的脚本
perl -ple 's%^[^/]*$%%; s%(?:^[^/]*?)((?:^|~)?/)[^/]*$%$1%; s%(?:^[^/]*?)((?:^|~)?/.*/).*%$1%' data
对原来的表达方式稍作修改后,最后才出现。
第一个CCD_ 38查找没有任何CCD_。
第二个s///
查找带斜线的行,可能前面有波浪号或行首,后面是非斜线,最后是带可选波浪号和斜线的行尾。
在匹配的情况下,前两个的输出与第三个s///
不匹配。
修订后的输出
~/dir1/di r2/
/dir1/di r2/
~/dir1/di r3/
~/name/more/still/more/
~//
/
~/
~/
/
/c/