我有一个小的正则表达式可以将整数值拆分为 1000,我只是想知道它是如何工作的。
这是一个perl代码。
$intval = 10000;
$intval =~ s/([+-]?\d)(?=(\d{3})+(?!\d))/$1,/go;
print $intval;
(...)
任何正常的括号集都是一个捕获组,可以在正则表达式匹配后引用,使用特殊变量$1
,$2
等。
[+-]?
括号创建一个字符组,意思是“匹配这些字符中的任何一个”。 ?
意思是“匹配零次或一次”。因此,这允许在比赛开始时出现单个 + 或 - 的可能性。
\d
匹配单个数字。
(?=...)
这是一个前瞻。它将要求模式中包含的所有内容都匹配,但不包括在输出“匹配”中。它也不会将字符串中的位置向前移动(这意味着在使用前瞻时匹配可以重叠)。
(\d{3})+
匹配一组或多组三位数。
(?!\d)
匹配的东西后面不能跟另一个数字。
/$1,/
用第一个捕获组替换匹配的内容(请记住,这不包括前瞻部分,因为这不算作匹配的一部分),后跟逗号。
go
这些标志是设置正则表达式行为的选项:
g
意味着它会重复,直到 if 找到并替换所有匹配项。o
是一种优化,告诉解释器只编译一次模式,但它在很大程度上已经过时并且在这种情况下完全没有区别,因为没有任何内容被插入到模式中。所以这个正则表达式将替换一个数字,后跟一些是三的倍数的数字,该数字后跟一个逗号。它反复运行,找到所有匹配项。这样做的效果是插入逗号作为千位分隔符。
一个小问题:这[+-]?
部分完全没有必要。因为正则表达式对数字前面的内容没有要求,所以即使删除了这部分,带有 + 或 - 的数字也可以正常工作。
任何时候你有这样的疑问,简单的出路,使用Yape::Regex::Explain
#!perl -w
use strict;
use YAPE::Regex::Explain;
print YAPE::Regex::Explain->new(qr/([+-]?\d)(?=(\d{3})+(?!\d))/)->explain();
产生这个
The regular expression:
(?-imsx:([+-]?\d)(?=(\d{3})+(?!\d)))
matches as follows:
NODE EXPLANATION
----------------------------------------------------------------------
(?-imsx: group, but do not capture (case-sensitive)
(with ^ and $ matching normally) (with . not
matching \n) (matching whitespace and #
normally):
----------------------------------------------------------------------
( group and capture to \1:
----------------------------------------------------------------------
[+-]? any character of: '+', '-' (optional
(matching the most amount possible))
----------------------------------------------------------------------
\d digits (0-9)
----------------------------------------------------------------------
) end of \1
----------------------------------------------------------------------
(?= look ahead to see if there is:
----------------------------------------------------------------------
( group and capture to \2 (1 or more times
(matching the most amount possible)):
----------------------------------------------------------------------
\d{3} digits (0-9) (3 times)
----------------------------------------------------------------------
)+ end of \2 (NOTE: because you are using a
quantifier on this capture, only the
LAST repetition of the captured pattern
will be stored in \2)
----------------------------------------------------------------------
(?! look ahead to see if there is not:
----------------------------------------------------------------------
\d digits (0-9)
----------------------------------------------------------------------
) end of look-ahead
----------------------------------------------------------------------
) end of look-ahead
----------------------------------------------------------------------
) end of grouping
----------------------------------------------------------------------
g
模式匹配需要全局完成o
模式必须编译一次查看 perlre修饰符以获取有关正则表达式修饰符的更多信息