/1.1/s/1/-/g
我正在做学校作业以参考实现 sed 命令。我得到这个字符串来匹配“/1/-/”。我有实验
$str =~ m{/[^/]*/[^/]*/}g;
但结果是/1.1/s/。我怎样才能只得到“/1/-/” 有人可以帮助我吗?
使用
/[^/]*/[^/]*/(?=[^/]*$)
参见证明。
解释
--------------------------------------------------------------------------------
/ '/'
--------------------------------------------------------------------------------
[^/]* any character except: '/' (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
/ '/'
--------------------------------------------------------------------------------
[^/]* any character except: '/' (0 or more times
(matching the most amount possible))
--------------------------------------------------------------------------------
/ '/'
--------------------------------------------------------------------------------
(?= look ahead to see if there is:
--------------------------------------------------------------------------------
[^/]* any character except: '/' (0 or more
times (matching the most amount
possible))
--------------------------------------------------------------------------------
$ before an optional \n, and the end of
the string
--------------------------------------------------------------------------------
) end of look-ahead
请记住,正则表达式引擎通常更喜欢最左边的最长匹配。
查找模式的最后一个匹配项的正则表达式习惯用法是在其前面加上
^.*
前缀。量词是贪婪的,因此 .*
从目标字符串的左端开始,吞噬右端的所有内容,并返回尽可能少的内容以使匹配成功。
前导
^
锚点并不是绝对必要的,但我发现它更能唤起人们对正在发生的事情的回忆。
适用于您的案例变成
$str = "/1.1/s/1/-/g";
if ($str =~ m{^.*(/[^/]*/[^/]*/)}) {
print "Last match: [$1]\n";
}
else {
print "No match: $str\n";
}
在线尝试或执行下面等效的 JavaScript 片段。无论哪种方式,输出都是
Last match: [/1/-/]
const str = '/1.1/s/1/-/g';
const pattern = new RegExp('^.*(/[^/]*/[^/]*/)');
let m;
if ((m = str.match(pattern)) !== null) {
console.log(`Last match: [${m[1]}]`);
}
else {
console.log(`No match: - ${str}`);
}