使用正则表达式匹配数字 - 仅数字和逗号

2024-02-11

我无法弄清楚如何为示例值构建正则表达式:

123,456,789
-12,34
1234
-8

你可以帮帮我吗?


什么是数字?

我有一个简单的问题your“简单”问题:“一个数字”到底是什么意思?

  • Is −0一个号码?
  • 你对这个怎么看√−1?
  • Is or 一个号码?
  • Is 186,282.42±0.02英里/秒是一个数字——还是其中的两个或三个?
  • Is 6.02e23一个号码?
  • Is 3.141_592_653_589一个号码?怎么样π, or ? And −2π⁻³ ͥ?
  • 中有多少个数字0.083̄?
  • 中有多少个数字128.0.0.1?
  • 什么数字是抓住?怎么样⚂⚃?
  • Does 10,5 mm里面有一个数字——还是有两个?
  • Is ∛8³一个数字——还是三个?
  • 什么数字是ↀↀⅮⅭⅭⅬⅫ AUC代表2762还是2009?
  • Are ४५६७ and ৭৮৯৮数字?
  • 关于什么0377, 0xDEADBEEF, and 0b111101101?
  • Is Inf一个号码?是NaN?
  • Is ④②一个号码?关于什么?
  • 你对这个怎么看?
  • What do ℵ₀ and ℵ₁和数字有关系吗?或者, , and ?

建议模式

另外,你熟悉这些模式吗?您能解释一下各自的优缺点吗?

  1. /\D/
  2. /^\d+$/
  3. /^\p{Nd}+$/
  4. /^\pN+$/
  5. /^\p{Numeric_Value:10}$/
  6. /^\P{Numeric_Value:NaN}+$/
  7. /^-?\d+$/
  8. /^[+-]?\d+$/
  9. /^-?\d+\.?\d*$/
  10. /^-?(?:\d+(?:\.\d*)?|\.\d+)$/
  11. /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/
  12. /^((\d)(?(?=(\d))|$)(?(?{ord$3==1+ord$2})(?1)|$))$/
  13. /^(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))$/
  14. /^(?:(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}):(?:[0-9a-fA-F]{1,2}))$/
  15. /^(?:(?:[+-]?)(?:[0123456789]+))$/
  16. /(([+-]?)([0123456789]{1,3}(?:,?[0123456789]{3})*))/
  17. /^(?:(?:[+-]?)(?:[0123456789]{1,3}(?:,?[0123456789]{3})*))$/
  18. /^(?:(?i)(?:[+-]?)(?:(?=[0123456789]|[.])(?:[0123456789]*)(?:(?:[.])(?:[0123456789]{0,}))?)(?:(?:[E])(?:(?:[+-]?)(?:[0123456789]+))|))$/
  19. /^(?:(?i)(?:[+-]?)(?:(?=[01]|[.])(?:[01]{1,3}(?:(?:[,])[01]{3})*)(?:(?:[.])(?:[01]{0,}))?)(?:(?:[E])(?:(?:[+-]?)(?:[01]+))|))$/
  20. /^(?:(?i)(?:[+-]?)(?:(?=[0123456789ABCDEF]|[.])(?:[0123456789ABCDEF]{1,3}(?:(?:[,])[0123456789ABCDEF]{3})*)(?:(?:[.])(?:[0123456789ABCDEF]{0,}))?)(?:(?:[G])(?:(?:[+-]?)(?:[0123456789ABCDEF]+))|))$/
  21. /((?i)([+-]?)((?=[0123456789]|[.])([0123456789]{1,3}(?:(?:[_,]?)[0123456789]{3})*)(?:([.])([0123456789]{0,}))?)(?:([E])(([+-]?)([0123456789]+))|))/

我怀疑上面的一些模式may满足您的需求。但我无法告诉你是哪一个或哪一个——或者,如果没有,则为你提供另一个——因为你还没有说出“数字”的含义。

如你所见,有一个巨大的数字可能性的数量:事实上,很可能有 ℵ₁ 的价值。 ☺

建议模式的关键

下面列出的每个编号说明描述了上面列出的相应编号模式的模式。

  1. 如果有则匹配非数字字符串中的任何位置,包括空格(如换行符)。
  2. 仅当字符串仅包含数字时才匹配,尾随换行符可能除外。请注意,数字被定义为具有属性“常规类别十进制数”,该属性可用作\p{Nd}, \p{Decimal_Number}, or \p{General_Category=Decimal_Number}。这实际上只是那些数字类型类别为 Decimal 的代码点的反映,可用作\p{Numeric_Type=Decimal}.
  3. 这与大多数正则表达式语言中的 2 相同。 Java 是一个例外,因为它不映射简单的 charclass 转义符,例如\w and \W, \d and \D, \s and \S, and \b or \B到适当的 Unicode 属性中。这意味着您不能对 Java 中的任何 Unicode 数据使用这八个单字符转义中的任何一个,因为它们仅适用于 ASCII,即使 Java 始终在内部使用 Unicode 字符。
  4. 这与 3 略有不同,它不限于十进制数,而是可以是任何数字;那是, 任何带有\pN, \p{Number}, or \p{General_Category=Number}财产。这些包括\p{Nl} or \p{Letter_Number}对于诸如罗马数字之类的东西\p{No} or \p{Other_Number}用于下标和下标数字、分数和带圆圈的数字 - 除其他外,例如计数棒。
  5. 这只匹配那些完全由十进制值为 10 的数字组成的字符串,所以像罗马数字十,以及, , , , , , and .
  6. 仅那些包含缺少数值 NaN 的字符的字符串;换句话说,所有字符都必须具有某个数值。
  7. 仅匹配十进制数字,可以选择带有前导连字符减号。
  8. 与 7 相同,但现在如果符号是加号而不是减号也可以使用。
  9. 查找十进制数字,带有可选的连字符减号和可选的句号以及后面零个或多个十进制数字。
  10. 与 9 相同,但如果点后有数字,则不需要点前有数字。
  11. C 和许多其他语言的标准浮点表示法,允许使用科学记数法。
  12. 查找仅由任何脚本的两位或更多小数按降序排列组成的数字,例如 987 或 54321。此递归正则表达式包括对 Perl 代码的调用,该代码检查前瞻数字是否具有当前数字的后继代码点值;也就是说,它的序数值大一。可以在 PCRE 中使用 C 函数作为标注来完成此操作。
  13. 这将查找有效范围内具有四个十进制数字的有效 IPv4 地址,例如 128.0.0.1 或 255.255.255.240,但不是 999.999.999.999。
  14. 这会查找有效的 MAC 地址,即六个冒号分隔的两个 ASCII 十六进制数字对。
  15. 这会查找 ASCII 范围内带有可选前导符号的整数。这是匹配 ASCII 整数的正常模式。
  16. 这与 15 类似,只是需要用逗号分隔三组。
  17. 这与 15 类似,只是用于分隔组的逗号现在是可选的。
  18. 这是匹配 ASCII 中的 C 风格浮点数的正常模式。
  19. 这类似于 18,但需要用逗号来分隔 3 组,并且以 2 为基数,而不是以 10 为基数。
  20. 这就像 19,但是是十六进制的。请注意,可选指数现在由 G 而不是 E 表示,因为 E 是有效的十六进制数字。
  21. 这会检查字符串是否包含 C 样式浮点数,但有一个可选的分组分隔符,每三位数字之间有一个逗号或下划线(LOW LINE)。它还将该字符串存储到\1捕获组,使其可用为$1比赛成功后。

来源和可维护性

模式编号 1,2,7–11 来自 Perl 的早期版本经常问的问题列出问题“如何验证输入?”。该部分已被建议使用正则表达式::常见 http://search.cpan.org/perldoc?Regexp::Common模块,编写者Abigail http://search.cpan.org/~abigail/ and 达米安·康威 http://search.cpan.org/~dconway/。原始模式仍然可以在食谱 2.1 中找到。Perl 食谱 http://oreilly.com/catalog/9780596003135,“检查字符串是否为有效数字”,可以为令人眼花缭乱的多种语言找到解决方案,包括 ada、common lisp、groovy、guile、haskell、java、merd、ocaml、php、pike、python、 rexx、ruby 和 tclPLEAC项目 http://pleac.sourceforge.net/.

模式 12 可以重写得更清晰

m{
    ^
    (
        ( \d )
        (?(?= ( \d ) ) | $ )
        (?(?{ ord $3 == 1 + ord $2 }) (?1) | $ )
    )
    $
}x

It uses 正则表达式递归 https://stackoverflow.com/questions/4031112/regular-expression-matching/4034386#4034386,它存在于许多模式引擎中,包括 Perl 和所有 PCRE 派生语言。但它也使用嵌入的代码标注作为其第二个条件模式的测试;据我所知,代码标注仅在 Perl 和 PCRE 中可用。

模式 13-21 源自前面提到的 Regexp::Common 模块。请注意,为了简洁起见,这些内容都没有包含您在生产代码中肯定需要的空格和注释。这可能是这样的/x mode:

$real_rx = qr{ (   # start $1 to hold entire pattern
    ( [+-]? )                  # optional leading sign, captured into $2
    (                          # start $3
        (?=                    # look ahead for what next char *will* be
            [0123456789]       #    EITHER:  an ASCII digit
          | [.]                #    OR ELSE: a dot
        )                      # end look ahead
        (                      # start $4
           [0123456789]{1,3}       # 1-3 ASCII digits to start the number
           (?:                     # then optionally followed by
               (?: [_,]? )         # an optional grouping separator of comma or underscore
               [0123456789]{3}     # followed by exactly three ASCII digits
           ) *                     # repeated any number of times
        )                          # end $4
        (?:                        # begin optional cluster
             ( [.] )               # required literal dot in $5
             ( [0123456789]{0,} )  # then optional ASCII digits in $6
        ) ?                        # end optional cluster
     )                         # end $3
    (?:                        # begin cluster group
        ( [E] )                #   base-10 exponent into $7
        (                      #   exponent number into $8
            ( [+-] ? )         #     optional sign for exponent into $9
            ( [0123456789] + ) #     one or more ASCII digits into $10
        )                      #   end $8
      |                        #   or else nothing at all
    )                          # end cluster group
) }xi;          # end $1 and whole pattern, enabling /x and /i modes

从软件工程的角度来看,中使用的风格仍然存在几个问题/x模式版本就在上面。首先,有大量的代码重复,你会看到相同的内容[0123456789];如果其中一个序列不小心遗漏了一个数字,会发生什么?其次,您依赖于必须计算的位置参数。这意味着你可能会写这样的内容:

(
  $real_number,          # $1
  $real_number_sign,     # $2
  $pre_exponent_part,    # $3
  $pre_decimal_point,    # $4
  $decimal_point,        # $5
  $post_decimal_point,   # $6
  $exponent_indicator,   # $7
  $exponent_number,      # $8
  $exponent_sign,        # $9
  $exponent_digits,      # $10
) = ($string =~ /$real_rx/);

坦率地说,这是令人憎恶的!编号很容易出错,很难记住符号名称在哪里,而且写起来很乏味,尤其是当您不需要所有这些部分时。将其重写为使用命名组而不仅仅是编号组。同样,我将使用 Perl 语法作为变量,但模式的内容应该适用于支持命名组的任何地方。

use 5.010;              # Perl got named patterns in 5.10
$real_rx = qr{
  (?<real_number>
    # optional leading sign
    (?<real_number_sign> [+-]? )
    (?<pre_exponent_part>
        (?=                         # look ahead for what next char *will* be
            [0123456789]            #    EITHER:  an ASCII digit
          | [.]                     #    OR ELSE: a dot
        )                           # end look ahead
        (?<pre_decimal_point>
            [0123456789]{1,3}       # 1-3 ASCII digits to start the number
            (?:                     # then optionally followed by
                (?: [_,]? )         # an optional grouping separator of comma or underscore
                [0123456789]{3}     # followed by exactly three ASCII digits
            ) *                     # repeated any number of times
         )                          # end <pre_decimal_part>
         (?:                        # begin optional anon cluster
            (?<decimal_point> [.] ) # required literal dot
            (?<post_decimal_point>
                [0123456789]{0,}  )
         ) ?                        # end optional anon cluster
   )                                # end <pre_exponent_part>
   # begin anon cluster group:
   (?:
       (?<exponent_indicator> [E] ) #   base-10 exponent
       (?<exponent_number>          #   exponent number
           (?<exponent_sign>   [+-] ?         )
           (?<exponent_digits> [0123456789] + )
       )                      #   end <exponent_number>
     |                        #   or else nothing at all
   )                          # end anon cluster group
 )                            # end <real_number>
}xi;

现在抽象被命名了,这很有帮助。您可以按名称提取组,并且只需要您关心的组。例如:

if ($string =~ /$real_rx/) {
    ($pre_exponent, $exponent_number) =
        @+{ qw< pre_exponent exponent_number > };
}

为了使其更易于维护,还需要做一件事来实现此模式。问题是仍然有太多重复,这意味着在一个地方很容易改变,但在另一个地方却很难改变。如果您正在进行 McCabe 分析,您会说它的复杂性指标太高了。我们大多数人都会说它太缩进了。这使得很难跟上。为了解决所有这些问题,我们需要一种“语法模式”,一种带有定义块来创建命名抽象的模式,然后我们将其视为稍后在比赛中的子例程调用。

use 5.010;              # Perl first got regex subs in v5.10
$real__rx = qr{ 

    ^                   # anchor to front
    (?&real_number)     # call &real_number regex sub
    $                   # either at end or before final newline

  ##################################################
  # the rest is definition only; think of         ##
  # each named buffer as declaring a subroutine   ##
  # by that name                                  ##
  ##################################################
  (?(DEFINE)
      (?<real_number>
          (?&mantissa)
          (?&abscissa) ?

      )
      (?<abscissa>
          (?&exponent_indicator)
          (?&exponent)
      )
      (?<exponent>
          (&?sign)    ?
          (?&a_digit) +
      )
      (?<mantissa>
         # expecting either of these....
         (?= (?&a_digit)
           | (?&point)
         )
         (?&a_digit) {1,3}
         (?: (?&digit_separator) ?
             (?&a_digit) {3}
         ) *
         (?: (?&point)
             (?&a_digit) *
         ) ?
      )
      (?<point>               [.]     )
      (?<sign>                [+-]    )
      (?<digit_separator>     [_,]    )
      (?<exponent_indicator>  [Ee]    )
      (?<a_digit>             [0-9]   )
   ) # end DEFINE block
}x;

See how 好得多语法模式比原来的线路噪音模式更好?获得正确的语法也容易得多:我输入的内容甚至没有一个需要纠正的正则表达式语法错误。 (好吧,我输入的所有其他内容也没有任何语法错误,但我已经这样做了一段时间了。:)

语法模式看起来更像 BNF,而不是人们讨厌的丑陋的旧正则表达式。它们更容易阅读、编写和维护。所以我们不要再有丑陋的模式了,好吗?

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用正则表达式匹配数字 - 仅数字和逗号 的相关文章

  • 在Windows应用程序中创建一个文本文件

    我想打开一个文本文件并向该文件写入一些数据 这是我的代码 FileStream fs1 new FileStream D Yourfile txt FileMode OpenOrCreate FileAccess Write StreamW
  • 椭圆绘制WPF动画

    我正在开发一个矩形区域的控件 当触发发生时 将在矩形区域中绘制一个椭圆形 该控件将能够承载其他控件 例如文本框 按钮等 因此在触发时将在它们周围绘制圆圈 我希望将圆圈绘制为动画 就像您用笔圈出内部控件一样 实现这一目标的最佳方法是什么 我一
  • WCF WebGetAttribute 与 WebInvokeAttribute

    WebGetAttribute 只是 Method GET 的 WebInvokeAttribute 的语法糖吗 或者有根本的区别吗 您立即观察到 WebGet 和 WebInvoke 非常相似 这与事实相差不远 正如您已经说过的 WebG
  • 提取字符串中最后一个句点后的文本[重复]

    这个问题在这里已经有答案了 我意识到这个问题对于大多数正则表达式大师来说可能看起来非常简单 但是回顾类似的问题并没有得出解决方案 我有一个电子邮件地址向量 称为email并希望在每个最后一个句点之后提取文本 举例来说 email lt c
  • 从 C# 程序集中执行 JavaScript

    我想从 C 程序集中执行 JavaScript 代码 并将 JavaScript 代码的结果返回到调用 C 代码 定义我不想做的事情更容易 我并不是试图从我的代码隐藏中调用网页上的 JavaScript 函数 我不想加载 WebBrowse
  • 确保 HttpConfiguration.EnsureInitialized()

    我已经安装了 Visual Studio 2013 当我运行我的应用程序时 出现以下错误 我不知道在哪里初始化这个对象 该怎么办 Server Error in Application The object has not yet been
  • 检测活动 RDP 会话

    我需要在我的应用程序中实现死人开关 如果应用程序从 RDP 运行 我需要在它失去与远程客户端的连接时采取行动 我知道当我在 RDP 中运行时使用 GetSystemMetrics SystemMetric SM REMOTESESSION
  • MVVM 中的事件而不是命令?

    在MVVM的各种教程中经常会指出 MVVM的目标不是消除代码隐藏 并且代码隐藏中的一些事件处理可能仍然是必要的 在什么场景下您需要在代码隐藏中编写事件而不是在视图模型中使用命令 一般来说 如果您的代码与 UI 逻辑相关 请将其保留在视图的
  • 使用 DrawImage 方法黑屏

    我必须使用绘制位图图像绘图上下文 DrawImage http msdn microsoft com en us library ms606804 28v vs 90 29 aspx method 使用下面的代码一切正常 BitmapIma
  • 如何动态调用动态对象的方法?

    当我想在 C 中的任何对象上动态调用静态定义的 静态 是指 在编译时确定 的意义上 而不是 类级成员 的意义上 方法时 我可以使用反射获取该方法的句柄并调用它 typeof Foo GetMethod Bar Invoke foo new
  • .NET 中的 base_convert

    NET 是否具有与 PHP 等效的本机功能基数转换 http php net base convert或者我需要自己写 我想从任何基数转换为任何其他基数 其中 to 基数或 from 基数可以是 2 36 的任何整数 PHP 函数示例 ba
  • 时间:2019-03-17 标签:c#usbdecision

    我们当前的应用程序中有几个进程 一个进程处理 USB 加载程序的检测和删除 处理检测和删除的代码如下 protected override void WndProc ref Message m switch m Msg case Win32
  • 如何从捆绑 .spec.js 文件中排除 webpack

    我的 Package bundle 读取 var reqContext require context true js reqContext keys map reqContext 其中基本上包括所有 js 文件 我希望表达式排除任何 sp
  • 如何从网络客户端获取状态码?

    我正在使用WebClient类将一些数据发布到 Web 表单 我想获取表单提交的响应状态代码 到目前为止我已经找到了如果出现异常如何获取状态代码 Catch wex As WebException If TypeOf wex Respons
  • 是否可以防止 DataGridView 中出现多行 HeaderText?

    当长度为HeaderText属性达到一定的字符限制并且文本中有空格 WinForms 会自动在标题中插入链接中断 我想要的是 Measurement Value 我得到什么 Measurement Value 有足够的空间来显示所有标题单元
  • 将 .Net-Repeater 与 jquery 结合使用

    我有一个中继器 ASP Net
  • 如何使用 System.Json 进行漂亮的打印?

    使用新的System Json 从 4 5 开始 http msdn microsoft com en us library system json 28v vs 95 29 aspx或同等的来自 Nuget 的 4 0 的 System
  • Random 并行生成数字 1 的次数超过 90% [重复]

    这个问题在这里已经有答案了 考虑以下程序 public class Program private static Random rnd new Random private static readonly int ITERATIONS 50
  • 在 10 亿次迭代中获得相同 GUID 的机会有多大?

    我正在开展一个项目 需要生成大约 10 亿个 GUID 我知道 GUID 不能保证是唯一的 但几乎始终是唯一的 如果我生成了十亿个 GUID 那么匹配的概率是多少 博客文章 GUID 是全局唯一的 但 GUID 的子字符串不是 https
  • 正则表达式中 (*) 和 .* 有什么区别? [复制]

    这个问题在这里已经有答案了 是任意字符零次或多次 我试图找到以元音开头的单词 我用了 aeiou 它给了我所有以元音开头的单词 当我这样做时给出相同的结果 aeiou 现在我正在寻找以元音结尾的单词 我做到了 aeiou 它没有给出任何结果

随机推荐