gpt4 book ai didi

regex - float 的正则表达式

转载 作者:行者123 更新时间:2023-12-03 05:01:16 25 4
gpt4 key购买 nike

我有一个任务来匹配浮点数。我为它编写了以下正则表达式:

[-+]?[0-9]*\.?[0-9]*

但是,它返回一个错误:

Invalid escape sequence (valid ones are  \b  \t  \n  \f  \r  \"  \'  \\ )

据我所知,我们需要为 . 使用转义字符。还有。请纠正我的错误。

最佳答案

TL; 博士

使用 [.] 代替 \.[0-9] 代替 \d 以避免转义某些语言(如 Java)中的问题。

感谢 the nameless one 最初认识到这一点。

匹配 浮点数的一种相对简单的模式是

[+-]?([0-9]*[.])?[0-9]+

这将匹配:
  • 123
  • 123.456
  • .456

  • 查看 working example

    如果您还想匹配 123.(一个没有小数部分的句点),那么您需要一个稍长的表达式:
    [+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)

    请参阅 pkeller's answer 以获取有关此模式的更完整说明

    如果您想包含非十进制数字,例如十六进制和八进制,请参阅我对 How do I identify if a string is a number? 的回答。

    如果你想 验证 输入是一个数字(而不是在输入中找到一个数字),那么你应该用 ^$ 包围模式,如下所示:
    ^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$

    不规则正则表达式

    在大多数现代语言、API、框架、库等中实现的“正则表达式”基于 formal language theory 中开发的概念。但是,软件工程师添加了许多扩展,使这些实现远远超出了正式定义。因此,虽然大多数正则表达式引擎彼此相似,但实际上并没有标准。因此,很大程度上取决于您使用的语言、API、框架或库。

    (顺便说一句,为了帮助减少混淆,许多人已经开始使用“ regex ”或“ regexp ”来描述这些增强的匹配语言。有关更多信息,请参见 Is a Regex the Same as a Regular Expression?

    也就是说,大多数正则表达式引擎(实际上,据我所知,所有这些引擎)都会接受 \. 。最有可能的是,逃逸有问题。

    逃跑的麻烦

    某些语言内置了对正则表达式 such as JavaScript 的支持。对于那些没有的语言,转义可能是一个问题。

    这是因为您基本上是用一种语言中的一种语言进行编码。例如,Java 使用 \ 作为其字符串中的转义字符,因此如果要在字符串中放置文字反斜杠字符,则必须对其进行转义:
    // creates a single character string: "\"
    String x = "\\";

    但是,正则表达式也使用 \ 字符进行转义,因此如果要匹配文字 \ 字符,则必须为正则表达式引擎对其进行转义,然后为 Java 再次转义:
    // Creates a two-character string: "\\"
    // When used as a regex pattern, will match a single character: "\"
    String regexPattern = "\\\\";

    在您的情况下,您可能没有在您正在编程的语言中转义反斜杠字符:
    // will most likely result in an "Illegal escape character" error
    String wrongPattern = "\.";
    // will result in the string "\."
    String correctPattern = "\\.";

    所有这些逃避都会变得非常困惑。如果您使用的语言支持 raw strings ,那么您应该使用它们来减少反斜杠的数量,但并非所有语言都支持(最值得注意的是:Java)。幸运的是,有一种替代方法可以在某些时候起作用:
    String correctPattern = "[.]";

    对于正则表达式引擎, \.[.] 的意思完全一样。请注意,这并不适用于所有情况,例如换行符 ( \\n )、左方括号 ( \\[ ) 和反斜杠 ( \\\\[\\] )。

    关于匹配数字的注意事项

    (提示:这比你想象的要难)

    匹配数字是您认为使用正则表达式很容易的事情之一,但实际上非常棘手。让我们一块一块地看一下你的方法:
    [-+]?

    匹配可选的 -+
    [0-9]*

    匹配 0 个或多个连续数字
    \.?

    匹配一个可选的 .
    [0-9]*

    匹配 0 个或多个连续数字

    首先,我们可以通过对数字使用 character class shorthand 来稍微清理一下这个表达式(请注意,这也容易受到上面提到的转义问题的影响):
    [0-9] = \d
    我将在下面使用 \d ,但请记住,它与 [0-9] 的含义相同。 (嗯,实际上,在某些引擎中 \d 会匹配所有脚本中的数字,所以它会比 [0-9] 匹配的更多,但这对你来说可能并不重要。)

    现在,如果你仔细观察,你会发现 模式的每个部分都是可选的 。此模式可以匹配长度为 0 的字符串;仅由 +- 组成的字符串;或者,一个仅由 . 组成的字符串。这可能不是你想要的。

    为了解决这个问题,首先用最低要求的字符串“ anchor 定”你的正则表达式是有帮助的,可能是一个数字:
    \d+

    现在我们想添加小数部分,但它不会出现在您认为可能的位置:
    \d+\.?\d* /* This isn't quite correct. */

    这仍将匹配 123. 之类的值。更糟糕的是,它有一个关于它的 tinge of evil。句点是可选的,这意味着您有两个并排重复的类( \d+\d* )。如果以错误的方式使用,这实际上可能很危险,使您的系统容易受到 DoS 攻击。

    为了解决这个问题,我们需要将句点视为可选的,而不是将其视为可选的(以分隔重复的字符类),而是将整个小数部分设为可选:
    \d+(\.\d+)? /* Better. But... */

    这现在看起来好多了。我们需要第一个数字序列和第二个数字序列之间有一个句点,但有一个致命的缺陷:我们无法匹配 .123 因为现在需要一个前导数字。

    这实际上很容易修复。与其将数字的“小数”部分设为可选,我们需要将其视为字符序列:1 个或多个可能以 . 为前缀的数字,而 ^ 可能以 0 个或多个数字为前缀:
    (\d*\.)?\d+

    现在我们只需添加符号:
    [+-]?(\d*\.)?\d+

    当然,这些斜线在 Java 中很烦人,所以我们可以在我们的长格式字符类中替换:
    [+-]?([0-9]*[.])?[0-9]+

    匹配与验证

    这在评论中出现了几次,所以我添加了一个关于匹配与验证的附录。

    匹配 的目标是在输入中找到一些内容(“大海捞针”)。 验证 的目标是确保输入的格式符合预期。

    正则表达式,就其性质而言,只有 匹配 文本。给定一些输入,他们要么会找到一些匹配的文本,要么不会。但是,通过使用 anchor 标记( $[+-]?([0-9]*[.])?[0-9]+ )将表达式“捕捉”到输入的开头和结尾,我们可以确保找不到匹配项,除非整个输入与表达式匹配,有效地使用正则表达式来 验证

    上述正则表达式 ( 1.34 ) 将 匹配 目标字符串中的一个或多个数字。所以给定输入:
    apple 1.34 pear 7.98 version 1.2.3.4

    正则表达式将匹配 7.981.2.3.41.2

    要验证给定的输入是一个数字,而只是一个数字,请通过将其包装在 anchor 标记中来将表达式“对齐”到输入的开头和结尾:
    ^[+-]?([0-9]*[.])?[0-9]+$

    如果整个输入是浮点数,这只会找到匹配项,如果输入包含其他字符,则不会找到匹配项。因此,给定输入 apple 1.2 pear ,将找到匹配项,但给定 validate 找不到匹配项。

    请注意,某些正则表达式引擎具有 isMatchtrue 或类似函数,它们基本上自动执行我所描述的操作,如果找到匹配项则返回 false ,如果未找到匹配项则返回 ^ 。还请记住,某些引擎允许您设置更改 $ 和 ojit_code 定义的标志,匹配行的开头/结尾而不是整个输入的开头/结尾。这通常不是默认设置,但要注意这些标志。

    关于regex - float 的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12643009/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com