1

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

这是一个perl代码。

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

2 回答 2

6

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

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

\d匹配单个数字。

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

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

(?!\d)匹配的东西后面不能跟另一个数字。

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

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

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

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

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

于 2013-01-31T11:42:54.880 回答
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模式必须编译一次

查看 perlre修饰符以获取有关正则表达式修饰符的更多信息

于 2013-01-31T12:32:33.720 回答