我希望在第一个斜杠之前匹配第一个和最后一个斜杠/
之间的所有内容,包括可选的~
。
我在第一部分使用了这个:
echo ~~a~/dir1/di r2/b.c \
| perl -pe 's/[^\/]*(\/.*\/).*/\1/'
产生/dir1/di r2/
。
此匹配包括代字号:
perl -pe 's/
的 * (
的〜 \/.*\/).*/\1/'
但为可选字符添加?
似乎在这些情况下无效:
perl -pe 's/
。* (
〜? \/.*\/).*/\1/'
- > /di r2/
perl -pe 's/
。* (
(?:〜) \/.*\/).*/\1/'
- > ~~a/dir1/di r2/b.c
我做错了什么?
答案 0 :(得分:1)
如果我理解了所需的输出权,那么无论是否使用波形符都可以使用
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
。将{}
用于分隔符只允许不必转义/
,从而使其更具可读性 - 但是当使用/
作为分隔符然后在其中转义时,同样有效。
更新
要抓住单独的~/
(或/
),最简单的更改是明确添加/.*/ | /
。为了在两种情况下捕获(optinal)~
,在此周围存在(非捕获)分组。删除-w
标志,这样当输入字符串根本没有斜线时,不会发出警告,但只打印一个空行。
答案 1 :(得分:1)
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%
第一部分(?:^.*?)
是一行非捕获非贪婪匹配,用于行开头的任意字符序列。
第二部分((?:^|~)/.*/)
是一个捕获表达式,其中包含一个非捕获术语,该术语在行的开头或波浪号处匹配,后跟斜杠和贪婪的任何内容,直到最后一个斜杠在线。
尾随.*
匹配第二部分之后的所有内容。
替换就是被捕获的东西;其余的是Perl是Perl。
原来的问题陈述似乎不完整。显然:
对于单斜杠,它应该仅输出
/
(如果存在则伴随波形符)。对于没有斜线,最好是空字符串,因为没有匹配。 ...对于这种情况~a b/c/d.f
,它返回完整的字符串;相反,它应该返回/c/
。
所以,这是一个修改过的脚本来处理特殊的额外案例(发生了什么事情以及学习如何捕鱼&#39 ;?)。 ~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
最后对原始表达进行了温和修改。
第一个s///
查找没有任何/
的行,并将其替换为空。
第二个s///
查找带有斜杠的行,可能在波浪号或行首之前,后跟非斜杠到行尾的可选波形符和斜杠。
匹配时前两个的输出与第三个s///
不匹配。
~/dir1/di r2/
/dir1/di r2/
~/dir1/di r3/
~/name/more/still/more/
~//
/
~/
~/
/
/c/