165

浮動小数点数を照合するタスクがあります。次の正規表現を作成しました。

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

ただし、エラーが返されます。

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

私の知る限り、エスケープ文字.も使用する必要があります。私が間違っているところを訂正してください。

4

16 に答える 16

359

TL; DR

一部の言語(Javaなど)での問題の回避を回避するために、の[.]代わりにを使用してください。\.[0-9]\d

もともとこれを認識してくれた無名の人に感謝します。

より大きな文字列の浮動小数点数を照合するための比較的単純なパターンの1つは次のとおりです。

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

これは一致します:

  • 123
  • 123.456
  • .456

実例を見る

(小数部のないピリオド)も一致させたい場合123.は、少し長い式が必要になります。

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

このパターンの詳細については、pkellerの回答を参照してください。

科学的記数法や、16進数や8進数などの非小数の数値など、より広い範囲の数値を含める場合は、「文字列が数値であるかどうかを識別するにはどうすればよいですか?」の回答を参照してください。

入力が数値であることを検証する場合(入力内で数値を見つけるのではなく)、次のようにパターンを^とで囲む必要があります。$

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

不規則な正規表現

ほとんどの現代言語、API、フレームワーク、ライブラリなどで実装されている「正規表現」は、形式言語理論で開発された概念に基づいています。ただし、ソフトウェアエンジニアは、これらの実装を正式な定義をはるかに超えたものにする多くの拡張機能を追加しました。したがって、ほとんどの正規表現エンジンは互いに似ていますが、実際には標準はありません。このため、使用している言語、API、フレームワーク、またはライブラリに大きく依存します。

(ちなみに、混乱を減らすために、多くの人が「regex」または「regexp」を使用してこれらの拡張マッチング言語を説明しています。詳細については、 RexEgg.comの「正規表現と同じですか?」を参照してください。)

とは言うものの、ほとんどの正規表現エンジン(実際には、私が知る限り、それらすべて)はを受け入れ\.ます。ほとんどの場合、エスケープに問題があります。

脱出のトラブル

一部の言語には、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\\[\\\\[\\]

一致する番号に関する注意

(ヒント:思ったより難しいです)

数値を一致させることは、正規表現を使用すると非常に簡単だと思うことの1つですが、実際にはかなり注意が必要です。あなたのアプローチを少しずつ見てみましょう:

[-+]?

オプション-または+

[0-9]*

0個以上の連続した数字に一致する

\.?

オプションに一致する.

[0-9]*

0個以上の連続した数字に一致する

まず、数字の省略形の文字クラスを使用して、この式を少しクリーンアップできます(これは、上記のエスケープの問題の影響も受けやすいことに注意してください)。

[0-9]=\d

以下で使用し\dますが、と同じ意味であることに注意して[0-9]ください。(実際、一部のエンジンで\dはすべてのスクリプトの数字と一致するため、より多く一致します[0-9]が、あなたの場合はおそらく重要ではありません。)

これを注意深く見ると、パターンのすべての部分がオプションであることがわかります。このパターンは、長さ0の文字列と一致する可能性があります。+またはのみで構成される文字列-。または、。のみで構成される文字列.。これはおそらくあなたが意図したものではありません。

これを修正するには、正規表現を最低限必要な文字列(おそらく1桁)で「固定」することから始めると便利です。

\d+

ここで小数部を追加したいのですが、思ったとおりに進みません。

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

これは、のような値と一致します123.。さらに悪いことに、それはそれについて悪の色合いを持っています。ピリオドはオプションです。つまり、2つの繰り返しクラスが並んでいます(\d+\d*)。これは、間違った方法で使用すると実際には危険であり、システムがDoS攻撃にさらされる可能性があります。

これを修正するには、ピリオドをオプションとして扱うのではなく、必要に応じて(繰り返される文字クラスを分離するために)扱い、代わりに小数部分全体をオプションにする必要があります。

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

これは今良く見えています。最初の数字のシーケンスと2番目の数字の間にピリオドが必要ですが、致命的な欠陥があり.123ます。先頭の数字が必要になったため、一致させることができません。

これは実際には非常に簡単に修正できます。数字の「10進数」部分をオプションにする代わりに、文字のシーケンスとして見る必要があります.。0個以上の数字が接頭辞として付けられる可能性のあるaが接頭辞として付けられる可能性のある1つ以上の数字:

(\d*\.)?\d+

ここで、記号を追加します。

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

もちろん、これらのスラッシュはJavaではかなり煩わしいので、長い形式の文字クラスで置き換えることができます。

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

マッチングと検証

これはコメントで数回出てきたので、マッチングと検証に関する補遺を追加します。

マッチングの目的は、入力内のコンテンツ(「干し草の山の中の針」)を見つけることです。検証の目的は、入力が期待される形式であることを確認することです。

正規表現は、その性質上、テキストにのみ一致します。いくつかの入力が与えられると、一致するテキストが見つかるか、見つからないかのどちらかです。ただし、アンカータグ(^および$)を使用して式を入力の最初と最後に「スナップ」することで、入力全体が式と一致しない限り一致が見つからないようにすることができ、正規表現を効果的に使用して検証します。

上記の正規表現([+-]?([0-9]*[.])?[0-9]+)は、ターゲット文字列内の1つ以上の数値と一致します。したがって、入力が与えられます:

apple 1.34 pear 7.98 version 1.2.3.4

正規表現は、、、、およびに一致1.34します。7.981.2.3.4

指定された入力が数値であり、数値にすぎないことを検証するには、式をアンカータグでラップして、入力の開始と終了に「スナップ」します。

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

これは、入力全体が浮動小数点数である場合にのみ一致を検出し、入力に追加の文字が含まれている場合は一致を検出しません。したがって、入力が与えられると、一致は見つかりますが、一致1.2が与えられapple 1.2 pearない場合は見つかりません。

一部の正規表現エンジンには、、validateまたはisMatch同様の関数があります。これは基本的に、私が説明したことを自動的に実行し、true一致が見つかった場合と一致が見つからfalseなかった場合に返されます。また、一部のエンジンでは、入力全体の開始/終了ではなく、行の開始/終了に一致する^との定義を変更するフラグを設定できることにも注意してください。$これは通常、デフォルトではありませんが、これらのフラグに注意してください。

于 2012-09-28T15:37:00.790 に答える
35

この記事を書いている時点では、このページの回答はどれも正しいとは思いません(SOに関する他の多くの提案も間違っています)。複雑なのは、次のすべての可能性に一致する必要があることです。

  • 小数点なし(つまり整数値)
  • 小数点の前後の数字(例0.3522.165
  • 小数点の前の数字のみ(例0.1234.
  • 小数点以下の数字のみ(例.0.5678

同時に、どこかに少なくとも1桁あることを確認する必要があります。つまり、次のことは許可されていません。

  • それ自体の小数点
  • 数字のない符号付き小数点(つまり+.、または-.
  • +または-自分で
  • 空の文字列

これは最初は注意が必要なようですが、インスピレーションを見つける1つの方法は、メソッドのOpenJDKソースを調べることです( http://hg.openjdk.java.net/jdk8/jdk8/jdkjava.lang.Double.valueOf(String)から開始し、[参照]をクリックして、下に移動します)。クラスを見つけます)。このクラスに含まれる長い正規表現は、OPがおそらく考えていなかったさまざまな可能性に対応しますが、NaN、無限大、16進表記、および指数を扱う部分を単純化するために無視し、POSIX表記ではなく1桁の場合、指数なしで符号付き浮動小数点数の正規表現の重要な部分を減らすことができます。/src/share/classes/java/lang/Double\d

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

(...)|(...)数字を含まないものを許可したり、小数点の前に数字がない、または小数点の後に数字がない可能性の1つを禁止せずに、構造を回避する方法はないと思います。

明らかに実際には、正規表現自体またはそれを使用するコードのいずれかで、末尾または先行の空白に対応する必要があります。

于 2017-03-06T15:17:39.490 に答える
21

ほとんどの言語が有効な数値(整数と浮動小数点数)と見なすものと一致させたい:

  • '5' / '-5'

  • '1.0' / '1.' / '.1' / '-1.' / '-.1'

  • '0.45326e+04', '666999e-05', '0.2e-3', '-33.e-1'

ノート:

  • preceding sign of number ('-' or '+') is optional

  • '-1.' and '-.1' are valid but '.' and '-.' are invalid

  • '.1e3' is valid, but '.e3' and 'e3' are invalid

両方の「1」をサポートするため。および「.1」は、「。」を確実に除外するために、OR演算子(「|」)が必要です。マッチングから。

[+-]??0または1が一致することを意味するため、+/-singはオプションです

(2つのサブ式があるので、それらを括弧で囲む必要があります

\d+([.]\d*)?(e[+-]?\d+)?これは、数字で始まる数字用です

|サブ式を区切ります

[.]\d+(e[+-]?\d+)?これは、「。」で始まる数字用です。

)式の終わり

  • '。'で始まる数字の場合

[.]最初の文字はドットです(角かっこ内、またはワイルドカード文字)

\d+1桁以上

(e[+-]?\d+)?これはオプションです(「?」で終わるため、0または1の一致)科学的記数法

  • 数字で始まる数字の場合

\d+1桁以上

([.]\d*)?オプションで、ドット文字の後に0桁以上を含めることができます

(e[+-]?\d+)?これはオプションの科学的記数法です

  • 科学的記数法

e指数を指定するリテラル

[+-]?オプションの指数記号

\d+1桁以上

それらすべてを組み合わせたもの:

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

E同様に受け入れるには:

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

テストケース

于 2019-04-09T12:04:52.597 に答える
8

必要なものは次のとおりです。

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

「+」と「-」の記号をエスケープし、「1」のようなものなので、小数点を次の数字でグループ化しました。は有効な番号ではありません。

変更により、整数と浮動小数点数を一致させることができます。例えば:

0
+1
-2.0
2.23442
于 2012-09-28T15:35:50.600 に答える
8

これは簡単です。Javaを使用したことが\\.あり、代わりに使用する必要があります\.(Javaでエスケープする文字を検索してください)。

于 2015-03-27T17:09:21.077 に答える
3

これは私のために働いた:

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

これを使用することもできます(名前付きパラメーターなしで):

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

いくつかのオンライン正規表現テスターを使用してテストします(例:regex101)

于 2015-10-17T13:52:34.910 に答える
2
^[+-]?([0-9]{1,})[.,]([0-9]{1,})$

これは一致します:

  1. 1.2
  2. 12.3
  3. 123.4
  4. 1,2
  5. 12,3
  6. 123,4
于 2017-02-24T10:57:51.857 に答える
1

javascriptの場合

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

これは1.231234.2200.1212で機能します

のパーツを変更して{}、小数の長さと小数の前部で異なる結果を得ることができます。これは、入力で使用され、数字を入力し、入力時にすべての入力をチェックして、通過するものだけを許可します。

于 2018-02-01T20:10:26.550 に答える
1

これは、C /C++コードで認識される浮動小数点数をキャプチャします。

[+-]?((((\d+\.?\d*)|(\.\d+))([eE][+-]?\d+[fF]?)?)|((\d+\.\d*)|(\.\d+))[fF]?)
  • +/-記号
  • 数字、数字、.digitsまたはdigits.digitsのいずれかのみ
  • eまたはE、+/-符号および数字を含むオプションの指数
  • 末尾にオプションのfまたはFがありますが、数値に。が含まれている場合に限ります。または指数
于 2021-04-08T06:03:35.773 に答える
1
(\d*)(\.)*(\d+)

これにより、以下が解析されます。

11.00
12
.0

番号は1つでなければなりません。小数点と小数点の前の数字はオプションです。

于 2021-09-19T00:59:41.273 に答える
0
[+-]?(([1-9][0-9]*)|(0))([.,][0-9]+)?

[+-]?-オプションの先行記号

(([1-9][0-9]*)|(0))-先行ゼロのない整数(単一のゼロを含む)

([.,][0-9]+)?-オプションの小数部

于 2015-11-11T10:22:09.640 に答える
0
[+/-] [0-9]*.[0-9]+

このソリューションを試してください。

于 2016-10-31T13:05:36.353 に答える
0

正規表現ライブラリを使用するC++の場合

答えは次のようになります。

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

記号記号を使用しないことに注意してください。記号記号を使用したい場合は、次のようになります。

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

これにより、通常の数値または10進数も分離されます。

于 2019-05-19T02:34:00.267 に答える
0

c表記では、浮動小数点数は次の形で発生する可能性があります。

  1. 123
  2. 123。
  3. 123.24
  4. .24
  5. 2e-2 = 2 * 10 pow -2 = 2 * 0.1
  6. 4E + 4 = 4*10パウ4=4 * 10000

float regular expresionを作成するには、最初に「intregularexpresionvariable」を作成します。

(([1-9][0-9]*)|0) will be int

ここで、floatの通常の式の小さなチャンクを記述します。解決策は、これらのチャンクを「|」または記号で連結することです。

チャンク:

- (([+-]?{int}) satysfies case 1
- (([+-]?{int})"."[0-9]*)  satysfies cases 2 and 3
- ("."[0-9]*) satysfies case 4
- ([+-]?{int}[eE][+-]?{int}) satysfies cases 5 and 6

最終的な解決策(小さな塊をまとめる):

(([+-]?{int})|(([+-]?{int})"."[0-9]*)|("."[0-9]*)|([+-]?{int}[eE][+-]?{int})
于 2020-03-09T22:00:16.057 に答える
0

ユーザーが入力したすべての文字の符号付き浮動小数点数である必要がある入力全体を検証する正規表現を検索する場合。

つまり、記号が最初に表示され(一致して有効である必要があります)、次にすべての数字(一致して有効である必要があります)とそのオプションの小数部分が表示されます。

JSでは、onkeydown/ oninputeventを使用してそれを行います+次の正規表現:

^[+-]?[0-9]*([\.][0-9]*)?$
于 2021-01-14T10:54:11.603 に答える
0

C言語では、答えは次のようになります。

[+-]?((\d+\.?\d*)|(\.\d+))(([eE][+-]?)?\d+)?[fFlL]?
于 2021-11-07T17:28:32.997 に答える