在“高级正则表达式”一章中掌握 Perl http://oreilly.com/catalog/9780596527242,我有一个损坏的示例,我无法找到一个很好的修复方法。这个例子可能为了自己的利益而试图变得太聪明,但也许有人可以帮我解决它。里面可能有这本书的免费副本,用于修复工作。 :)
在讨论环视的部分中,我想使用负环视来实现带有小数部分的数字的通信例程。重点是使用负面回顾,因为这就是主题。
我愚蠢地这样做了:
$_ = '$1234.5678';
s/(?<!\.\d)(?<=\d)(?=(?:\d\d\d)+\b)/,/g; # $1,234.5678
The (?<!\.\d)
断言之前的位(?=(?:\d\d\d)+\b)
不是小数点和数字。
愚蠢的事情是没有足够努力去打破它。通过在末尾添加另一个数字,现在有一组前面没有小数点和数字的三位数字:
$_ = '$1234.56789';
s/(?<!\.\d)(?<=\d)(?=(?:\d\d\d)+\b)/,/g; # $1,234.56,789
如果 Perl 中的后视可以是可变宽度,那么这将非常容易。但他们不能。
请注意,在没有负向后查找的情况下很容易做到这一点,但这不是示例的重点。有办法挽救这个例子吗?
我认为如果没有某种形式的可变宽度后视是不可能的。添加的\K
5.10 中的断言提供了一种伪造可变宽度正向后查找的方法。我们真正需要的是可变宽度negative向后看,但只要有一点创造力和很多丑陋,我们就可以让它发挥作用:
use 5.010;
$_ = '$1234567890.123456789';
s/(?<!\.)(?:\b|\G)\d+?\K(?=(?:\d\d\d)+\b)/,/g;
say; # $1,234,567,890.123456789
如果有一种模式需要/x
符号就是这个:
s/
(?<!\.) # Negative look-behind assertion; we don't want to match
# digits that come after the decimal point.
(?: # Begin a non-capturing group; the contents anchor the \d
# which follows so that the assertion above is applied at
# the correct position.
\b # Either a word boundary (the beginning of the number)...
| # or (because \b won't match at subsequent positions where
# a comma should go)...
\G # the position where the previous match left off.
) # End anchor grouping
\d+? # One or more digits, non-greedily so the match proceeds
# from left to right. A greedy match would proceed from
# right to left, the \G above wouldn't work, and only the
# rightmost comma would get placed.
\K # Keep the preceding stuff; used to fake variable-width
# look-behind
# <- This is what we match! (i.e. a position, no text)
(?= # Begin a positive look-ahead assertion
(?:\d\d\d)+ # A multiple of three digits (3, 6, 9, etc.)
\b # A word (digit) boundary to anchor the triples at the
# end of the number.
) # End positive look-ahead assertion.
/,/xg;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)