TL; DR
一部の言語(Javaなど)でエスケープの問題を回避するために、[.]
代わりに\.
およびの[0-9]
代わりに使用し\d
ます。
もともとこれを認識してくれた無名の方に感謝します。
浮動小数点数を照合するための比較的単純なパターンの1つは、
[+-]?([0-9]*[.])?[0-9]+
これは一致します:
実際の例を見る
123.
(小数部のないピリオド)も一致させたい場合は、少し長い式が必要になります。
[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+)
このパターンの詳しい説明については、pkellerの回答を参照してください
16進数や8進数などの10進数以外の数値を含める場合は、「文字列が数値かどうかを確認するにはどうすればよいですか?」に対する私の回答を参照してください。。
入力が数値であることを検証したい場合は(入力内の数値を見つけるのではなく)、次のようにパターンを^
and $
で囲む必要があります。
^[+-]?([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
)、開き角括弧(\\[
)、バックスラッシュ(\\\\
または[\\]
)のように、すべての場合で機能するわけではないことに注意してください。
番号の一致に関する注意
(ヒント:思ったより難しいです)
数を一致させることは、正規表現を使用すると非常に簡単だと思うことの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進数」の部分をオプションにする代わりに、文字のシーケンスとして.
見なす必要があります。
(\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.98
、1.2
、.3
と.4
。
指定された入力が数値であり、数値にすぎないことを検証するには、アンカータグでラップして、式を入力の開始と終了に「スナップ」します。
^[+-]?([0-9]*[.])?[0-9]+$
これは、入力全体が浮動小数点数の場合にのみ一致を検出し、入力に追加の文字が含まれている場合には一致を検出しません。したがって、入力1.2
が与えられるとapple 1.2 pear
一致が見つかりますが、一致が見つからないことになります。
一部の正規表現エンジンにはvalidate
、isMatch
または同様の機能があり、基本的には私が説明したことを自動的に実行し、true
一致が見つかった場合と一致が見つからfalse
なかった場合に返されます。また、一部のエンジンでは^
、およびの定義を変更するフラグを設定し$
て、入力全体の先頭/末尾ではなく、行の先頭/末尾に一致させることができることにも注意してください。通常、これはデフォルトではありませんが、これらのフラグに注意してください。