当前位置: 首页 > 面试题库 >

浮点数的正则表达式

云浩然
2023-03-14
问题内容

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

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

但是,它返回一个错误:

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

据我所知,我们还需要使用转义字符.。请纠正我哪里我错了。


问题答案:

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

感谢无名的人最初认识到这一点。

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

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

这将匹配:

  • 123
  • 123.456
  • .456

查看工作示例

如果您还想匹配123.(无小数点的句点),则需要稍长的表达式:

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

有关此模式的更详细说明,请参见pkeller的答案

如果要包括非十进制数字(例如十六进制和八进制),请参阅我的答案如何识别字符串是否为数字?。

如果要验证输入是否为数字(而不是在输入中查找数字),则应使用^和围绕模式$,如下所示:

^[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)$

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

(顺便说一句,为减少混乱,许多人开始使用“ regex ”或“ regexp ”来描述这些增强的匹配语言。有关更多信息,请参见RexEgg.com上的Regex是否与正则表达式相同?)

就是说,大多数正则表达式引擎(据我所知实际上全部都是)都可以接受.。转义很可能是一个问题。

逃生的麻烦
某些语言内置了对正则表达式的支持,例如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 = "\\.";

所有这些转义可能会造成非常混乱。如果您使用的语言支持原始字符串,那么您应该使用原始语言来减少反斜杠的数量,但并非所有语言都支持(例如,Java)。幸运的是,有一种替代方法有时会起作用:

String correctPattern = "[.]";

对于正则表达式引擎,\.[.]含义完全相同。请注意,这并非在所有情况下都有效,例如换行符(\\n),方括号(\\[)和反斜杠(\\\\[\\])。

有关匹配数字的注意事项
(提示:这比您想象的要难)

使用正则表达式,匹配数字是您认为很容易的事情之一,但实际上却很棘手。让我们一步一步地看一下您的方法:

[-+]?

匹配可选-或+

[0-9]*

匹配0个或多个连续数字

\.?

搭配可选 .

[0-9]*

匹配0个或多个连续数字

首先,我们可以通过使用数字的字符类缩写来稍微整理一下此表达式(请注意,这也容易受到上述转义问题的影响):

[0-9] = \d

我将在\d下面使用,但请记住,它的含义与相同[0-9]。(嗯,实际上,在某些引擎中,\d它将匹配所有脚本中的数字,因此它将比匹配的更多[0-9],但这在您的情况下可能并不重要。)

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

要解决此问题,从用最小的必需字符串(可能是一个数字)“固定”正则表达式开始会很有帮助:

\d+

现在,我们要添加小数部分,但是它没有到​​达您认为可能的位置:

\d+\.?\d* /* This isn't quite correct. */

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

要解决此问题,而不是将句点视为可选,我们需要按需对其进行处理(以分隔重复的字符类),而是使整个小数部分为可选:

\d+(\.\d+)? /* Better. But... */

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

这实际上很容易解决。除了将数字的“小数”部分设为可选字符之外,我们需要将其视为一个字符序列:1个或多个可能以a开头的数字,也.可能以0或多个数字为前缀:

(\d*\.)?\d+

现在我们只需添加符号:

[+-]?(\d*\.)?\d+

当然,这些斜线在Java中非常令人讨厌,因此我们可以替换为长格式字符类:

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

匹配与验证
评论中已经提到了几次,所以我在匹配和验证上添加了附录。

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

正则表达式本质上仅匹配文本。给定一些输入,他们要么找到一些匹配的文本,要么找不到。但是,通过使用锚标记(^和$)将表达式“捕捉”到输入的开头和结尾,我们可以确保没有找到匹配项,除非整个输入都匹配表达式,有效地使用了正则表达式进行验证。

上述正则表达式([+-]?([0-9]*[.])?[0-9]+)将匹配目标字符串中的一个或多个数字。因此,鉴于输入:

apple 1.34 pear 7.98 version 1.2.3.4

正则表达式匹配1.347.981.2.3.4

要验证给定输入是否为数字,什么都不是数字,请将表达式包装在锚定标记中,从而将表达式“捕捉”到输入的开头和结尾:

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

仅当整个输入为浮点数时,才会找到匹配项;如果输入包含其他字符,则不会找到匹配项。因此,给定输入1.2,将找到一个匹配项,但apple 1.2 pear没有找到匹配项。

需要注意的是一些正则表达式引擎有一个validateisMatch或类似的功能,基本上做什么,我已自动描述,返回true如果找到匹配且false如果没有发现匹配。也请记住,有些引擎允许你改变它的定义组标志^$,一条线的开始/结束,而不是整个输入的开始/结束匹配。通常这不是默认值,但是要注意这些标志。



 类似资料:
  • 问题内容: 因此,我对 正则表达式 完全 陌生 ,并且正在尝试使用Java 来查找输入字符串中的标点符号。我不知道会提前得到哪种标点符号,只是(1)!,?,。,…都是有效的标点符号,以及(2)“ <”和“>”表示特殊含义,并且不算作标点符号。该程序本身会伪随机地构建短语,我想在它经历随机过程之前先删除句子结尾处的标点符号。 我可以用任何标点符号匹配整个单词,但匹配器只为我提供该单词的索引。换一种说

  • 问题内容: 首先,我阅读以下文档 http://download.oracle.com/javase/1.4.2/docs/api/java/util/regex/Pattern.html 而且我想找到除@’之外的任何标点符号,但我不太了解。 这是 : 结果是没有匹配。 是否有任何不匹配? 谢谢 MRizq 问题答案: 您要匹配两个字符,而不是一个。使用(负)前瞻应解决以下任务:

  • 问题内容: 我需要找到与特定正则表达式匹配的所有软件包: 基本上,包的名字应该与启动,并有后话。例如,以下软件包应匹配: 我可以做,但是有很多我不感兴趣的软件包。 是否提供通过正则表达式查找软件包的方法?或者,我应该只是通过管道传递结果来过滤掉无关的包? 此外,可能是一个的“交集” ,并有助于太。 问题答案: alecxe,我相信这是您要寻找的一线客。 如下面评论中铬酸盐所建议的那样,您可以根据需

  • 问题内容: 我需要一个正则表达式 那么任何数字。并再次编号和。 所以这是有效的 但 无效 我尝试了以下模式: 但这些都不满足我的要求。请帮忙? 我现有的代码是 问题答案: 这样的事情应该起作用: 编辑 是的,不从该描述,如果最终清除被允许(假定一个初始是 不 )。 如果不: 或者 (如果看起来更合乎逻辑) 测试 产生:

  • 昨天,我需要向正则表达式添加一个文件路径,创建一个如下所示的模式: 一开始正则表达式不匹配,因为包含几个正则表达式特定的符号,如 或 。作为快速修复,我将它们替换为 和 . 与 . 然而,我问自己,是否没有一种更可靠或更好的方法来清除正则表达式特定符号中的字符串。 Python 标准库中是否支持此类功能? 如果没有,您是否知道一个正则表达式来识别所有正则表达式并通过替代品清理它们?

  • 有没有人试图描述与正则表达式匹配的正则表达式? 由于重复的关键字,这个主题几乎不可能在网上找到。 它可能在实际应用程序中不可用,因为支持正则表达式的语言通常具有解析它们的方法,我们可以将其用于验证,以及一种在代码中分隔正则表达式的方法,可用于搜索目的。 但是我仍然想知道匹配所有正则表达式的正则表达式是什么样子的。应该可以写一个。