-- Start
假设我们有这样的问题,把类似 3.690000023 的小数保留两位小数,类似 2.3563895 的小数保留三位小数,也就是说如果小数的第三位是 0, 则保留两位小数,如果是非 0, 就保留三位小数,该怎么呢? 这个问题比较简单,用下面的 Perl 代码。
$number =~ s/(.dd[1-9]?)d*/$1/;
这个表达式完全可以工作,美中不足的一点是,当 $number 类似 3.695 的时候,我们把 .695 替换为了 .695,浪费了工夫。为了解决这个问题,我们把表达式稍稍修改一下。
$number =~ s/(.dd[1-9]?)d+/$1/;
仅仅把星号替换成了加号,这样表示括号外至少有一位数字的时候才进行替换。看上去很完美,但是却出现了致命的错误,.695 被替换成了 .69了。这是为什么呢?在表达式 (.dd[1-9]?) 匹配了 .695 后, 后面的 d+ 无法匹配了,为了使整个表达式匹配成功,引擎必须回溯,[1-9]?必须把匹配的数字吐出去,所以 5 被 d+ 匹配了。这就是回溯造成的问题。事实上在这种情况下,我们不希望引擎回溯,有两种办法可以强迫引擎放弃回溯,固化分组和占有量词。
$number =~ s/(.dd(?>[1-9]?))d+/$1/; # 固化分组
$number =~ s/(.dd[1-9]?+)d+/$1/; # 占有量词
--更多参见:正则表达式精萃
-- 声 明:转载请注明出处
-- Last Updated on 2012-05-25
-- Written by ShangBo on 2012-05-25
-- End
本文发布于:2024-02-03 23:55:03,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170697992951880.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |