浮点数的正则表达式

时间:2022-02-24 11:34:27

I have a task to match floating point numbers. I have written the following regular expression for it :

我的任务是匹配浮点数。我已经写了以下的正则表达式:

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

But it shows an error saying :

但它显示了一个错误:

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

But as per my knowledge we need to use an escape character for the . also. Please correct me where I am wrong.

但是据我所知,我们需要用一个转义字符来表示。也。请纠正我的错误。

9 个解决方案

#1


142  

TL;DR

Use [.] instead of \. and [0-9] instead of \d to avoid escaping issues in some languages (like Java).

使用[。代替\]。和[0-9],而不是用一些语言(比如Java)避免问题。

One relatively simple pattern for matching a floating point number is

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

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

This will match:

这将匹配:

  • 123
  • 123年
  • 123.456
  • 123.456
  • .456
  • .456

See a working example

看到一个工作示例

If you also want to match 123. (a period with no decimal part), then you'll need a slightly longer expression:

如果你也想匹配123。(一个没有小数部分的周期),然后需要一个稍微长一点的表达式:

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

See pkeller's answer for a fuller explanation of this pattern

查看pkeller的答案来更全面地解释这个模式

If you want to include non-decimal numbers, such as hex and octal, see my answer to How do I identify if a string is a number?.

如果您想包含非十进制数,如十六进制和八进制,请参阅我如何识别字符串是否为数字的答案。

If you want to validate that an input is a number (rather than finding a number within the input), then you should surround the pattern with ^ and $, like so:

如果你想验证一个输入是一个数字(而不是内发现大量输入),那么您应该围绕^和$的模式,就像这样:

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

Irregular Regular Expressions

"Regular expressions", as implemented in most modern languages, APIs, frameworks, libraries, etc., are based on a concept developed in formal language theory. However, software engineers have added many extensions that take these implementations far beyond the formal definition. So, while most regular expression engines resemble one another, there is actually no standard. For this reason, a lot depends on what language, API, framework or library you are using.

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

(Incidentally, to help reduce confusion, many have taken to using "regex" or "regexp" to describe these enhanced matching languages. See Is a Regex the Same as a Regular Expression? at RexEgg.com for more information.)

(顺便说一句,为了减少混淆,许多人已经开始使用“regex”或“regexp”来描述这些增强的匹配语言。看,Regex是否与正则表达式相同?更多信息请访问RexEgg.com。

That said, most regex engines (actually, all of them, as far as I know) would accept \.. Most likely, there's an issue with escaping.

也就是说,大多数regex引擎(实际上,据我所知,它们都接受\.. .最有可能的是,有个问题要逃避。

The Trouble with Escaping

(Thanks to the nameless one for originally recognizing this.)

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

Some languages have built-in support for regexes, such as JavaScript. For those languages that don't, escaping can be a problem.

有些语言内置对regex的支持,比如JavaScript。对于那些没有的语言,转义可能是个问题。

This is because you are basically coding in a language within a language. Java, for example, uses \ as an escape character within it's strings, so if you want to place a literal backslash character within a string, you must escape it:

这是因为您基本上是在用一种语言编写代码。例如,Java在它的字符串中使用\作为转义字符,所以如果您想在字符串中放置一个字面的反斜杠字符,您必须转义它:

// creates a single character string: "\"
String x = "\\";

However, regexes also use the \ character for escaping, so if you want to match a literal \ character, you must escape it for the regexe engine, and then escape it again for Java:

然而,regexe也使用\字符进行转义,所以如果您想匹配一个文字\字符,您必须转义它用于regexe引擎,然后再转义它用于Java:

// Creates a two-character string: "\\"
// When used as a regex pattern, will match a single character: "\"
String regexPattern = "\\\\";

In your case, you have probably not escaped the backslash character in the language you are programming in:

在您的案例中,您可能没有从您正在编程的语言中摆脱反斜杠字符:

// will most likely result in an "Illegal escape character" error
String wrongPattern = "\.";
// will result in the string "\."
String correctPattern = "\\.";

All this escaping can get very confusing. If the language you are working with supports raw strings, then you should use those to cut down on the number of backslashes, but not all languages do (most notably: Java). Fortunately, there's an alternative that will work some of the time:

所有这些转义都会让人很困惑。如果使用的语言支持原始字符串,那么应该使用它们来减少反斜杠的数量,但不是所有语言都支持(最明显的是:Java)。幸运的是,有一种方法在某些时候会起作用:

String correctPattern = "[.]";

For a regex engine, \. and [.] mean exactly the same thing. Note that this doesn't work in every case, like newline (\\n), open square bracket (\\[) and backslash (\\\\ or [\\]).

用于regex引擎,\。和[。意思完全一样。注意,这并不是在所有情况下都适用,比如newline (\ n)、open square(\[\])和backslash(\(\\))。

A Note about Matching Numbers

(Hint: It's harder than you think)

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

Matching a number is one of those things you'd think is quite easy with regex, but it's actually pretty tricky. Let's take a look at your approach, piece by piece:

匹配一个数字是你认为使用regex很容易的事情之一,但实际上是相当棘手的。让我们一起来看看你的方法:

[-+]?

Match an optional - or +

匹配一个可选的-或+

[0-9]*

Match 0 or more sequential digits

匹配0或更多的连续数字

\.?

Match an optional .

匹配一个可选的。

[0-9]*

Match 0 or more sequential digits

匹配0或更多的连续数字

First, we can clean up this expression a bit by using a character class shorthand for the digits (note that this is also susceptible to the escaping issue mentioned above):

首先,我们可以通过对数字使用字符类速记来清理这个表达式(注意,这也容易受到上面提到的转义问题的影响):

[0-9] = \d

[0 - 9]= \ d

I'm going to use \d below, but keep in mind that it means the same thing as [0-9]. (Well, actually, in some engines \d will match digits from all scripts, so it'll match more than [0-9] will, but that's probably not significant in your case.)

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

Now, if you look at this carefully, you'll realize that every single part of your pattern is optional. This pattern can match a 0-length string; a string composed only of + or -; or, a string composed only of a .. This is probably not what you've intended.

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

To fix this, it's helpful to start by "anchoring" your regex with the bare-minimum required string, probably a single digit:

为了解决这个问题,从“锚定”你的正则表达式到最低要求的字符串(可能是一个数字)开始是很有帮助的。

\d+

Now we want to add the decimal part, but it doesn't go where you think it might:

现在我们想要加小数部分,但是它没有你想的那样:

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

This will still match values like 123.. Worse, it's got a tinge of evil about it. The period is optional, meaning that you've got two repeated classes side-by-side (\d+ and \d*). This can actually be dangerous if used in just the wrong way, opening your system up to DoS attacks.

这仍然会匹配像123这样的值。更糟糕的是,它还带有一丝邪恶。周期是可选的,这意味着您同时拥有两个重复类(\d+和\d*)。如果以错误的方式使用,这实际上是很危险的,这会导致系统受到DoS攻击。

To fix this, rather than treating the period as optional, we need to treat it as required (to separate the repeated character classes) and instead make the entire decimal portion optional:

要解决这个问题,而不是将周期视为可选的,我们需要将其视为必需的(以分离重复的字符类),而不是将整个小数部分作为可选的:

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

This is looking better now. We require a period between the first sequence of digits and the second, but there's a fatal flaw: we can't match .123 because a leading digit is now required.

现在看起来好多了。我们需要在第一个数字序列和第二个数字序列之间有一个周期,但是有一个致命的缺陷:我们不能匹配。123,因为现在需要一个前位数字。

This is actually pretty easy to fix. Instead of making the "decimal" portion of the number optional, we need to look at it as a sequence of characters: 1 or more numbers that may be prefixed by a . that may be prefixed by 0 or more numbers:

这其实很容易修正。我们不需要将数字的“十进制”部分作为可选部分,我们需要将它视为一个字符序列:1个或多个以a开头的数字。以0或以上的数字作为前缀:

(\d*\.)?\d+

Now we just add the sign:

现在我们只需要加上符号:

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

Of course, those slashes are pretty annoying in Java, so we can substitute in our long-form character classes:

当然,这些斜杠在Java中非常烦人,所以我们可以在我们的长格式字符类中替换:

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

Matching versus Validating

This has come up in the comments a couple times, so I'm adding an addendum on matching versus validating.

这在评论中已经出现过几次了,所以我在匹配和验证中添加了一个附录。

The goal of matching is to find some content within the input (the "needle in a haystack"). The goal of validating is to ensure that the input is in an expected format.

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

Regexes, by their nature, only match text. Given some input, they will either find some matching text or they will not. However, by "snapping" an expression to the beginning and ending of the input with anchor tags (^ and $), we can ensure that no match is found unless the entire input matches the expression, effectively using regexes to validate.

Regexes本质上只匹配文本。给定一些输入,它们要么找到匹配的文本,要么找不到。然而,通过“收购”输入一个表达式的开始和结束与锚标记(^和$),我们可以确保没有找到匹配,除非整个输入的表达式匹配,有效地使用正则表达式来验证。

The regex described above ([+-]?([0-9]*[.])?[0-9]+) will match one or more numbers within a target string. So given the input:

上面描述的正则表达式([+-]?[0-9]*[.])?[0-9]+[0-9]+)将匹配目标字符串中的一个或多个数字。所以考虑到输入:

apple 1.34 pear 7.98 version 1.2.3.4

The regex will match 1.34, 7.98, 1.2, .3 and .4.

regex将匹配1.34、7.98、1.2、.3和.4。

To validate that a given input is a number and nothing but a number, "snap" the expression to the start and end of the input by wrapping it in anchor tags:

为了验证一个给定的输入是一个数字,而不是一个数字,“snap”表达式到输入的开始和结束,将其封装在锚标记中:

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

This will only find a match if the entire input is a floating point number, and will not find a match if the input contains additional characters. So, given the input 1.2, a match will be found, but given apple 1.2 pear no matches will be found.

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

Note that some regex engines have a validate, isMatch or similar function, which essentially does what I've described automatically, returning true if a match is found and false if no match is found. Also keep in mind that some engines allow you to set flags which change the definition of ^ and $, matching the beginning/end of a line rather than the beginning/end of the entire input. This is typically not the default, but be on the lookout for these flags.

注意,有些regex引擎有一个验证、isMatch或类似的函数,它基本上自动执行我所描述的操作,如果找到匹配,返回true;如果没有找到匹配,返回false。还请记住,一些引擎允许您设置标志变化^和$的定义,匹配的开始/结束一行而不是整个输入的开始/结束。这通常不是默认设置,但是要注意这些标志。

#2


12  

I don't think that any of the answers on this page at the time of writing are correct (also many other suggestions elsewhere on SO are wrong too). The complication is that you have to match all of the following possibilities:

我不认为在这个页面上的任何答案都是正确的(也有很多其他的建议是错误的)。复杂的是,你必须匹配以下所有的可能性:

  • No decimal point (i.e. an integer value)
  • 没有小数点(即整数)
  • Digits both before and after the decimal point (e.g. 0.35 , 22.165)
  • 小数点前后的数字(例如0.35、22.165)
  • Digits before the decimal point only (e.g. 0. , 1234.)
  • 小数点前的数字(如0)。,1234)。
  • Digits after the decimal point only (e.g. .0 , .5678)
  • 小数点后的位数(例如。0,.5678)

At the same time, you must ensure that there is at least one digit somewhere, i.e. the following are not allowed:

与此同时,你必须确保某些地方至少有一位数字,即不允许下列数字出现:

  • a decimal point on its own
  • 一个小数点
  • a signed decimal point with no digits (i.e. +. or -.)
  • 没有数字的有符号小数点(即+)或-。)
  • + or - on their own
  • +或-靠自己。
  • an empty string
  • 一个空字符串

This seems tricky at first, but one way of finding inspiration is to look at the OpenJDK source for the java.lang.Double.valueOf(String) method (start at http://hg.openjdk.java.net/jdk8/jdk8/jdk, click "browse", navigate down /src/share/classes/java/lang/ and find the Double class). The long regex that this class contains caters for various possibilities that the OP probably didn't have in mind, but ignoring for simplicity the parts of it that deal with NaN, infinity, Hexadecimal notation and exponents, and using \d rather than the POSIX notation for a single digit, I can reduce the important parts of the regex for a signed floating point number with no exponent to:

乍一看,这似乎有点棘手,但找到灵感的一种方法是查看OpenJDK源代码,获取java.lang.Double.valueOf(String)方法(从http://hg.openjdk.java.net/jdk8/jdk8/jdk、单击“浏览”、向下导航/src/共享/类/java/lang/找到Double类)。漫长的正则表达式,这类包含满足各种可能性,OP可能没有记住,但是忽略简单的部分处理南,无穷,十六进制符号和指数,并使用\ d而不是POSIX符号为单个数字,我可以减少对签名的正则表达式的重要部分浮点数没有指数:

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

(+ -)?((\ d + \ ? \ d *)|(\ \ d +))。

I don't think that there is a way of avoiding the (...)|(...) construction without allowing something that contains no digits, or forbidding one of the possibilities that has no digits before the decimal point or no digits after it.

我不认为有一种方法可以避免(…)|(…)构造而不允许包含没有数字的东西,或者禁止在小数点前没有数字的可能性,或者在小数点后没有数字的可能性。

Obviously in practice you will need to cater for trailing or preceding whitespace, either in the regex itself or in the code that uses it.

显然,在实践中,您需要在regex本身或使用它的代码中处理尾随或之前的空格。

#3


7  

what you need is:

你需要的是:

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

I escaped the "+" and "-" sign and also grouped the decimal with its following digits since something like "1." is not a valid number.

我转义了“+”和“-”符号,并将小数与其下面的数字分组,因为“1”之类的数字不是有效数字。

The changes will allow you to match integers and floats. for example:

这些更改将允许您匹配整数和浮点数。例如:

0
+1
-2.0
2.23442

#4


2  

This is simple: you have used Java and you ought to use \\. instead of \. (search for character escaping in Java).

这很简单:您使用过Java,应该使用\\ \。而不是\。(在Java中搜索字符转义)。

#5


2  

This one worked for me:

这个对我很有用:

(?P<value>[-+]*\d+\.\d+|[-+]*\d+)

You can also use this one (without named parameter):

你也可以使用这个(没有命名参数):

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

Use some online regex tester to test it (e.g. regex101 )

使用一些在线regex测试器来测试它(例如regex101)

#6


0  

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

[+-]? - optional leading sign

(+ -)?-可选的主要标志

(([1-9][0-9]*)|(0)) - integer without leading zero, including single zero

([1-9][0-9]*)|(0) -无前导零的整数,包括单零

([.,][0-9]+)? - optional fractional part

([,][0 - 9]+)?-可选的小数部分

#7


0  

^[+]?([0-9]{1,2})*[.,]([0-9]{1,1})?$

This will match:

这将匹配:

  1. 1.2
  2. 1.2
  3. 12.3
  4. 12.3
  5. 1,2
  6. 1、2
  7. 12,3
  8. 12、3

#8


-1  

[+/-] [0-9]*.[0-9]+

Try this solution.

试试这个解决方案。

#9


-1  

for javascript

对javascript

const test = new RegExp('^[+]?([0-9]{0,})*[.]?([0-9]{0,2})?$','g');

Which would work for 1.23 1234.22 0 0.12 12

1。23 1234。22 0 0 0。12

You can change the parts in the {} to get different results in decimal length and front of the decimal as well. This is used in inputs for entering in number and checking every input as you type only allowing what passes.

您可以更改{}中的部分,以获得小数长度和小数点前面的不同结果。这是用于输入数字和检查每一个输入时,你只允许什么通过。

#1


142  

TL;DR

Use [.] instead of \. and [0-9] instead of \d to avoid escaping issues in some languages (like Java).

使用[。代替\]。和[0-9],而不是用一些语言(比如Java)避免问题。

One relatively simple pattern for matching a floating point number is

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

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

This will match:

这将匹配:

  • 123
  • 123年
  • 123.456
  • 123.456
  • .456
  • .456

See a working example

看到一个工作示例

If you also want to match 123. (a period with no decimal part), then you'll need a slightly longer expression:

如果你也想匹配123。(一个没有小数部分的周期),然后需要一个稍微长一点的表达式:

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

See pkeller's answer for a fuller explanation of this pattern

查看pkeller的答案来更全面地解释这个模式

If you want to include non-decimal numbers, such as hex and octal, see my answer to How do I identify if a string is a number?.

如果您想包含非十进制数,如十六进制和八进制,请参阅我如何识别字符串是否为数字的答案。

If you want to validate that an input is a number (rather than finding a number within the input), then you should surround the pattern with ^ and $, like so:

如果你想验证一个输入是一个数字(而不是内发现大量输入),那么您应该围绕^和$的模式,就像这样:

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

Irregular Regular Expressions

"Regular expressions", as implemented in most modern languages, APIs, frameworks, libraries, etc., are based on a concept developed in formal language theory. However, software engineers have added many extensions that take these implementations far beyond the formal definition. So, while most regular expression engines resemble one another, there is actually no standard. For this reason, a lot depends on what language, API, framework or library you are using.

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

(Incidentally, to help reduce confusion, many have taken to using "regex" or "regexp" to describe these enhanced matching languages. See Is a Regex the Same as a Regular Expression? at RexEgg.com for more information.)

(顺便说一句,为了减少混淆,许多人已经开始使用“regex”或“regexp”来描述这些增强的匹配语言。看,Regex是否与正则表达式相同?更多信息请访问RexEgg.com。

That said, most regex engines (actually, all of them, as far as I know) would accept \.. Most likely, there's an issue with escaping.

也就是说,大多数regex引擎(实际上,据我所知,它们都接受\.. .最有可能的是,有个问题要逃避。

The Trouble with Escaping

(Thanks to the nameless one for originally recognizing this.)

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

Some languages have built-in support for regexes, such as JavaScript. For those languages that don't, escaping can be a problem.

有些语言内置对regex的支持,比如JavaScript。对于那些没有的语言,转义可能是个问题。

This is because you are basically coding in a language within a language. Java, for example, uses \ as an escape character within it's strings, so if you want to place a literal backslash character within a string, you must escape it:

这是因为您基本上是在用一种语言编写代码。例如,Java在它的字符串中使用\作为转义字符,所以如果您想在字符串中放置一个字面的反斜杠字符,您必须转义它:

// creates a single character string: "\"
String x = "\\";

However, regexes also use the \ character for escaping, so if you want to match a literal \ character, you must escape it for the regexe engine, and then escape it again for Java:

然而,regexe也使用\字符进行转义,所以如果您想匹配一个文字\字符,您必须转义它用于regexe引擎,然后再转义它用于Java:

// Creates a two-character string: "\\"
// When used as a regex pattern, will match a single character: "\"
String regexPattern = "\\\\";

In your case, you have probably not escaped the backslash character in the language you are programming in:

在您的案例中,您可能没有从您正在编程的语言中摆脱反斜杠字符:

// will most likely result in an "Illegal escape character" error
String wrongPattern = "\.";
// will result in the string "\."
String correctPattern = "\\.";

All this escaping can get very confusing. If the language you are working with supports raw strings, then you should use those to cut down on the number of backslashes, but not all languages do (most notably: Java). Fortunately, there's an alternative that will work some of the time:

所有这些转义都会让人很困惑。如果使用的语言支持原始字符串,那么应该使用它们来减少反斜杠的数量,但不是所有语言都支持(最明显的是:Java)。幸运的是,有一种方法在某些时候会起作用:

String correctPattern = "[.]";

For a regex engine, \. and [.] mean exactly the same thing. Note that this doesn't work in every case, like newline (\\n), open square bracket (\\[) and backslash (\\\\ or [\\]).

用于regex引擎,\。和[。意思完全一样。注意,这并不是在所有情况下都适用,比如newline (\ n)、open square(\[\])和backslash(\(\\))。

A Note about Matching Numbers

(Hint: It's harder than you think)

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

Matching a number is one of those things you'd think is quite easy with regex, but it's actually pretty tricky. Let's take a look at your approach, piece by piece:

匹配一个数字是你认为使用regex很容易的事情之一,但实际上是相当棘手的。让我们一起来看看你的方法:

[-+]?

Match an optional - or +

匹配一个可选的-或+

[0-9]*

Match 0 or more sequential digits

匹配0或更多的连续数字

\.?

Match an optional .

匹配一个可选的。

[0-9]*

Match 0 or more sequential digits

匹配0或更多的连续数字

First, we can clean up this expression a bit by using a character class shorthand for the digits (note that this is also susceptible to the escaping issue mentioned above):

首先,我们可以通过对数字使用字符类速记来清理这个表达式(注意,这也容易受到上面提到的转义问题的影响):

[0-9] = \d

[0 - 9]= \ d

I'm going to use \d below, but keep in mind that it means the same thing as [0-9]. (Well, actually, in some engines \d will match digits from all scripts, so it'll match more than [0-9] will, but that's probably not significant in your case.)

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

Now, if you look at this carefully, you'll realize that every single part of your pattern is optional. This pattern can match a 0-length string; a string composed only of + or -; or, a string composed only of a .. This is probably not what you've intended.

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

To fix this, it's helpful to start by "anchoring" your regex with the bare-minimum required string, probably a single digit:

为了解决这个问题,从“锚定”你的正则表达式到最低要求的字符串(可能是一个数字)开始是很有帮助的。

\d+

Now we want to add the decimal part, but it doesn't go where you think it might:

现在我们想要加小数部分,但是它没有你想的那样:

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

This will still match values like 123.. Worse, it's got a tinge of evil about it. The period is optional, meaning that you've got two repeated classes side-by-side (\d+ and \d*). This can actually be dangerous if used in just the wrong way, opening your system up to DoS attacks.

这仍然会匹配像123这样的值。更糟糕的是,它还带有一丝邪恶。周期是可选的,这意味着您同时拥有两个重复类(\d+和\d*)。如果以错误的方式使用,这实际上是很危险的,这会导致系统受到DoS攻击。

To fix this, rather than treating the period as optional, we need to treat it as required (to separate the repeated character classes) and instead make the entire decimal portion optional:

要解决这个问题,而不是将周期视为可选的,我们需要将其视为必需的(以分离重复的字符类),而不是将整个小数部分作为可选的:

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

This is looking better now. We require a period between the first sequence of digits and the second, but there's a fatal flaw: we can't match .123 because a leading digit is now required.

现在看起来好多了。我们需要在第一个数字序列和第二个数字序列之间有一个周期,但是有一个致命的缺陷:我们不能匹配。123,因为现在需要一个前位数字。

This is actually pretty easy to fix. Instead of making the "decimal" portion of the number optional, we need to look at it as a sequence of characters: 1 or more numbers that may be prefixed by a . that may be prefixed by 0 or more numbers:

这其实很容易修正。我们不需要将数字的“十进制”部分作为可选部分,我们需要将它视为一个字符序列:1个或多个以a开头的数字。以0或以上的数字作为前缀:

(\d*\.)?\d+

Now we just add the sign:

现在我们只需要加上符号:

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

Of course, those slashes are pretty annoying in Java, so we can substitute in our long-form character classes:

当然,这些斜杠在Java中非常烦人,所以我们可以在我们的长格式字符类中替换:

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

Matching versus Validating

This has come up in the comments a couple times, so I'm adding an addendum on matching versus validating.

这在评论中已经出现过几次了,所以我在匹配和验证中添加了一个附录。

The goal of matching is to find some content within the input (the "needle in a haystack"). The goal of validating is to ensure that the input is in an expected format.

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

Regexes, by their nature, only match text. Given some input, they will either find some matching text or they will not. However, by "snapping" an expression to the beginning and ending of the input with anchor tags (^ and $), we can ensure that no match is found unless the entire input matches the expression, effectively using regexes to validate.

Regexes本质上只匹配文本。给定一些输入,它们要么找到匹配的文本,要么找不到。然而,通过“收购”输入一个表达式的开始和结束与锚标记(^和$),我们可以确保没有找到匹配,除非整个输入的表达式匹配,有效地使用正则表达式来验证。

The regex described above ([+-]?([0-9]*[.])?[0-9]+) will match one or more numbers within a target string. So given the input:

上面描述的正则表达式([+-]?[0-9]*[.])?[0-9]+[0-9]+)将匹配目标字符串中的一个或多个数字。所以考虑到输入:

apple 1.34 pear 7.98 version 1.2.3.4

The regex will match 1.34, 7.98, 1.2, .3 and .4.

regex将匹配1.34、7.98、1.2、.3和.4。

To validate that a given input is a number and nothing but a number, "snap" the expression to the start and end of the input by wrapping it in anchor tags:

为了验证一个给定的输入是一个数字,而不是一个数字,“snap”表达式到输入的开始和结束,将其封装在锚标记中:

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

This will only find a match if the entire input is a floating point number, and will not find a match if the input contains additional characters. So, given the input 1.2, a match will be found, but given apple 1.2 pear no matches will be found.

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

Note that some regex engines have a validate, isMatch or similar function, which essentially does what I've described automatically, returning true if a match is found and false if no match is found. Also keep in mind that some engines allow you to set flags which change the definition of ^ and $, matching the beginning/end of a line rather than the beginning/end of the entire input. This is typically not the default, but be on the lookout for these flags.

注意,有些regex引擎有一个验证、isMatch或类似的函数,它基本上自动执行我所描述的操作,如果找到匹配,返回true;如果没有找到匹配,返回false。还请记住,一些引擎允许您设置标志变化^和$的定义,匹配的开始/结束一行而不是整个输入的开始/结束。这通常不是默认设置,但是要注意这些标志。

#2


12  

I don't think that any of the answers on this page at the time of writing are correct (also many other suggestions elsewhere on SO are wrong too). The complication is that you have to match all of the following possibilities:

我不认为在这个页面上的任何答案都是正确的(也有很多其他的建议是错误的)。复杂的是,你必须匹配以下所有的可能性:

  • No decimal point (i.e. an integer value)
  • 没有小数点(即整数)
  • Digits both before and after the decimal point (e.g. 0.35 , 22.165)
  • 小数点前后的数字(例如0.35、22.165)
  • Digits before the decimal point only (e.g. 0. , 1234.)
  • 小数点前的数字(如0)。,1234)。
  • Digits after the decimal point only (e.g. .0 , .5678)
  • 小数点后的位数(例如。0,.5678)

At the same time, you must ensure that there is at least one digit somewhere, i.e. the following are not allowed:

与此同时,你必须确保某些地方至少有一位数字,即不允许下列数字出现:

  • a decimal point on its own
  • 一个小数点
  • a signed decimal point with no digits (i.e. +. or -.)
  • 没有数字的有符号小数点(即+)或-。)
  • + or - on their own
  • +或-靠自己。
  • an empty string
  • 一个空字符串

This seems tricky at first, but one way of finding inspiration is to look at the OpenJDK source for the java.lang.Double.valueOf(String) method (start at http://hg.openjdk.java.net/jdk8/jdk8/jdk, click "browse", navigate down /src/share/classes/java/lang/ and find the Double class). The long regex that this class contains caters for various possibilities that the OP probably didn't have in mind, but ignoring for simplicity the parts of it that deal with NaN, infinity, Hexadecimal notation and exponents, and using \d rather than the POSIX notation for a single digit, I can reduce the important parts of the regex for a signed floating point number with no exponent to:

乍一看,这似乎有点棘手,但找到灵感的一种方法是查看OpenJDK源代码,获取java.lang.Double.valueOf(String)方法(从http://hg.openjdk.java.net/jdk8/jdk8/jdk、单击“浏览”、向下导航/src/共享/类/java/lang/找到Double类)。漫长的正则表达式,这类包含满足各种可能性,OP可能没有记住,但是忽略简单的部分处理南,无穷,十六进制符号和指数,并使用\ d而不是POSIX符号为单个数字,我可以减少对签名的正则表达式的重要部分浮点数没有指数:

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

(+ -)?((\ d + \ ? \ d *)|(\ \ d +))。

I don't think that there is a way of avoiding the (...)|(...) construction without allowing something that contains no digits, or forbidding one of the possibilities that has no digits before the decimal point or no digits after it.

我不认为有一种方法可以避免(…)|(…)构造而不允许包含没有数字的东西,或者禁止在小数点前没有数字的可能性,或者在小数点后没有数字的可能性。

Obviously in practice you will need to cater for trailing or preceding whitespace, either in the regex itself or in the code that uses it.

显然,在实践中,您需要在regex本身或使用它的代码中处理尾随或之前的空格。

#3


7  

what you need is:

你需要的是:

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

I escaped the "+" and "-" sign and also grouped the decimal with its following digits since something like "1." is not a valid number.

我转义了“+”和“-”符号,并将小数与其下面的数字分组,因为“1”之类的数字不是有效数字。

The changes will allow you to match integers and floats. for example:

这些更改将允许您匹配整数和浮点数。例如:

0
+1
-2.0
2.23442

#4


2  

This is simple: you have used Java and you ought to use \\. instead of \. (search for character escaping in Java).

这很简单:您使用过Java,应该使用\\ \。而不是\。(在Java中搜索字符转义)。

#5


2  

This one worked for me:

这个对我很有用:

(?P<value>[-+]*\d+\.\d+|[-+]*\d+)

You can also use this one (without named parameter):

你也可以使用这个(没有命名参数):

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

Use some online regex tester to test it (e.g. regex101 )

使用一些在线regex测试器来测试它(例如regex101)

#6


0  

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

[+-]? - optional leading sign

(+ -)?-可选的主要标志

(([1-9][0-9]*)|(0)) - integer without leading zero, including single zero

([1-9][0-9]*)|(0) -无前导零的整数,包括单零

([.,][0-9]+)? - optional fractional part

([,][0 - 9]+)?-可选的小数部分

#7


0  

^[+]?([0-9]{1,2})*[.,]([0-9]{1,1})?$

This will match:

这将匹配:

  1. 1.2
  2. 1.2
  3. 12.3
  4. 12.3
  5. 1,2
  6. 1、2
  7. 12,3
  8. 12、3

#8


-1  

[+/-] [0-9]*.[0-9]+

Try this solution.

试试这个解决方案。

#9


-1  

for javascript

对javascript

const test = new RegExp('^[+]?([0-9]{0,})*[.]?([0-9]{0,2})?$','g');

Which would work for 1.23 1234.22 0 0.12 12

1。23 1234。22 0 0 0。12

You can change the parts in the {} to get different results in decimal length and front of the decimal as well. This is used in inputs for entering in number and checking every input as you type only allowing what passes.

您可以更改{}中的部分,以获得小数长度和小数点前面的不同结果。这是用于输入数字和检查每一个输入时,你只允许什么通过。