这个perl正则表达式如何工作?

时间:2013-01-31 11:33:01

标签: regex perl

我有一个小的正则表达式将一个整数值拆分为1000分隔,我只是想知道它是如何工作的。

这是一个perl代码。

$intval = 10000;
$intval =~ s/([+-]?\d)(?=(\d{3})+(?!\d))/$1,/go;
print $intval;

2 个答案:

答案 0 :(得分:6)

(...)任何正常的圆括号都是一个捕获组,可以在正则表达式匹配后使用特殊变量$1$2等进行引用。

[+-]?括号创建一个字符组,意思是“匹配任何这些字符”。 ?表示“匹配零次或一次”。因此,这允许在比赛开始时单个+或 - 的可能性。

\d匹配一个数字。

(?=...)这是一个预见。它将要求模式中包含的所有内容匹配,但不包括输出“匹配”中的内容。它也不会向前移动字符串中的位置(这意味着在使用前瞻时匹配可以重叠)。

(\d{3})+匹配一个或多个三位数组。

(?!\d)匹配的内容不能跟随另一个数字。

/$1,/用第一个捕获组替换匹配的内容(请记住,这不包括前瞻部分,因为这不算作匹配的一部分),后跟逗号。

go这些标志是设置正则表达式行为的选项:

  • g表示重复,直到找到并替换所有匹配项。
  • o是一个优化,告诉解释器只编译一次模式,但它在很大程度上已经过时,在这种情况下完全没有区别,因为没有任何内容插入到模式中。

因此,这个正则表达式将替换一个数字,后跟一个三位数的数字,该数字后跟一个逗号。它反复运行,找到所有匹配。这样做的效果是将逗号插入千位分隔符。

一个狡辩:[+-]?部分完全没必要。因为正则表达式对数字前面的内容没有要求,所以带有+或 - 的数字即使删除了这部分也能正常工作。

答案 1 :(得分:5)

任何时候你有这样的疑虑,轻松出路,使用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
----------------------------------------------------------------------
  1. g修饰符表示需要完成此模式匹配 全球
  2. o修饰符指定此模式必须为 编译一次
  3. 结帐perlre modifiers了解有关正则表达式修饰符的更多信息