33

正規表現では、1つまたは別のもの、あるいはその両方を(順番に)一致させる方法を知る必要があります。しかし、少なくとも1つはそこにある必要があります。

たとえば、次の正規表現

/^([0-9]+|\.[0-9]+)$/

一致します

234

.56

だがしかし

234.56

次の正規表現ながら

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

上記の3つの文字列すべてに一致しますが、不要な空の文字列にも一致します。

上記の3つの文字列すべてに一致するものが必要ですが、空の文字列には一致しません。それを行う簡単な方法はありますか?

アップデート:

以下のAndrewとJustinはどちらも、私が提供した単純化された例では機能しますが、(私が間違っていない限り)解決したいと思っていた実際のユースケースでは機能しないので、おそらく今すぐにそれを入れる必要があります。これが私が使用している実際の正規表現です:

/^\s*-?0*(?:[0-9]+|[0-9]{1,3}(?:,[0-9]{3})+)(?:\.[0-9]*)?(\s*|[A-Za-z_]*)*$/

これは一致します

45
45.988
45,689
34,569,098,233
567,900.90
-9
-34 banana fries
0.56 points

しかし、それは一致しません

.56

そして私はこれを行うためにそれが必要です。

4

5 に答える 5

38

正規表現が与えられた完全に一般的な方法/^A$/は次の/^B$/とおりです。

/^(A|B|AB)$/

すなわち

/^([0-9]+|\.[0-9]+|[0-9]+\.[0-9]+)$/

他の人があなたの例の構造を使って単純化したことに注意してください。具体的には、彼らは(暗黙的に)それを因数分解して、左右の共通点[0-9]*と因数分解を引き出しました。[0-9]+

このための作業は次のとおりです。

  • 交代のすべての要素はで終わる[0-9]+ので、それを引き出します:/^(|\.|[0-9]+\.)[0-9]+$/
  • これで、交互に空の文字列が含まれる可能性があるため、次のように書き直します?(つまり、同等のものを使用します(|a|b) = (a|b)?)。/^(\.|[0-9]+\.)?[0-9]+$/
  • 繰り返しますが、共通の接尾辞を持つ交互(\.今回):/^((|[0-9]+)\.)?[0-9]+$/
  • パターン(|a+)はと同じなa*ので、最後に:/^([0-9]*\.)?[0-9]+$/
于 2012-11-12T21:45:10.850 に答える
6

はい、これらすべてを次のような式と一致させることができます。

/^[0-9]*\.?[0-9]+$/

空の文字列(最後の条件)とも一致しないことに注意してください。

于 2012-11-12T21:42:01.687 に答える
4

もちろん。オプションの数量詞、が必要です?

/^(?=.)([0-9]+)?(\.[0-9]+)?$/

上記は少し見苦しいですが、いくつかのsがスローされた正確なパターンを示したいと思います?。このバージョンで(?=.)は、両方の句をオプションにしたため、空の文字列を受け入れないようにします。より単純なバージョンは次のようになります。

/^\d*\.?\d+$/

これは、空の文字列の防止など、要件を満たします。

これを表現する方法はたくさんあることに注意してください。長いものもあれば、非常に簡潔なものもありますが、許可/禁止しようとしているものによっては、より複雑になります

編集:

これをより大きな文字列内で一致させたい場合は、分割して結果を。でテストすることをお勧めし/^\d*\.?\d+$/ます。そうしないと、一致するものaaa.123.456.bbbや一致しないもののいずれかが発生するリスクがあります(信頼してください。JavaScriptには後読みサポートがないため、考えられるあらゆるパターンを破ることができます)。

上記のような文字列が得られないことがわかっている場合は、アンカーの代わりに単語の区切りを使用できますが、と(スペース)の^$間に単語の区切りがないため、複雑になります。.

/(\b\d+|\B\.)?\d*\b/g

それはそれをするべきです。のようなものをブロックしますが、、、、またはaaa123.456bbbを許可123します。それは可能ですが、私が言ったように、それを包括的に処理したい場合は、2つのステップが必要になります。456123.456aaa.123.456.bbb

編集2:ユースケース

最初に空白、負/正のマーク、最後に単語を許可したい場合、これらは実際にはかなり厳格なルールです。それは良いことです。上記の最も単純なパターンにそれらを追加することができます。

/^\s*[-+]?\d*\.?\d+[a-z_\s]*$/i

何千ものグループを許可すると、事態は非常に複雑になります。私がリンクした回答をご覧になることをお勧めします。結果のパターンは次のとおりです。

/^\s*[-+]?(\d+|\d{1,3}(,\d{3})*)?(\.\d+)?\b(\s[a-z_\s]*)?$/i

\b、数値部分が数字で終わり、その後に少なくとも1つの空白が続くことを保証します。

于 2012-11-12T21:42:42.900 に答える
4

huonによる良い答え(そして最後までそれに従うための少しの頭の体操)。この質問のタイトルに対する迅速で簡単な答えを探している人にとっては、「正規表現では、どちらか一方、または両方に一致する」ということは、(A | B | AB)でさえ次のように簡略化できることを言及する価値があります。

A|A?B

Bがもう少し複雑な場合に便利です。

于 2019-03-07T05:27:25.507 に答える
0

多分これは(あなたに一般的な考えを与えるために)役立つでしょう:

(?:((?(digits).^|[A-Za-z]+)|(?<digits>\d+))){1,2}

このパターンは、文字、数字、または文字に続く数字に一致しますが、数字に続く文字には一致しません。パターンはaa、aa11、および11と一致しますが、11aa、aa11aa、または空の文字列とは一致しません。「行頭が続く文字」を意味する「。^」に戸惑うことはありません。これは、一致を完全に防ぐことを目的としています。

これはすべての種類の正規表現で機能するわけではないことに注意してください。ご使用のバージョンの正規表現はをサポートする必要があります(?(named group)true|false)

于 2016-05-01T12:34:17.197 に答える