[01-12]の範囲が期待どおりに機能しないのはなぜですか?


91

[01-12]正規表現で範囲パターンを使用して2桁のmmに一致させようとしていますが、これは期待どおりに機能しません。


8
あなたは、一致している文字ではなく、文字列を。基本的には、0、1から1、および2(つまり、0、1、2)と照合します。これを考慮してください。これは[a-z0-9]、すべての小文字とすべての数字に一致しますが、1文字としてのみ一致します。
Lasse V. Karlsen、2010年

fwiw 2つの入力(最小/最大)から高度に最適化された正規表現を作成するjavascriptツールを作成しましたgithub.com/jonschlinkert/to-regex-range
jonschlinkert

正規表現の0 [1-9] | 1 [0-2]-> 0 | 1 | 2-> []は文字クラスを示します。範囲が指定されていない場合、暗黙的にすべての文字がorsされます。
Badri Gs 2017

純粋な正規表現と一致させる必要がありますか?そうでない場合は、次のことを実行できます。1。)\d+パターンを使用するだけです。2。)一致した文字列をコード内の数値に変換します。3.)のように番号範囲を確認しますif(num >= 0 && num <= 12){ /*do something*/ }。非常に高速で柔軟性があります。
acegs

回答:


192

正規表現で文字クラス定義がどのように機能するかを誤解しているようです。

文字列のいずれかに一致するには0102030405060708091011、または12、この作品のようなもの:

0[1-9]|1[0-2]

参考文献


説明

文字クラスは、それ自体で、入力文字列の1つの文字と正確に1つの文字を照合しようとします。[01-12]実際に定義し[012]、3つの文字のいずれかに対する入力から1つの文字に一致する文字クラスを01または2

-範囲の定義から行く11だけ含まれています、1。一方、のようなものが[1-9]含まれ123456789

初心者はしばしばのようなものを定義することの間違いを犯し[this|that]ます。これは「機能しません」。この文字の定義定義を[this|a]、すなわち、それは、6つの文字のいずれかに対する入力から1つの文字にマッチしthis|またはa。おそらく(this|that)意図されたものです。

参考文献


範囲の定義方法

したがって、のようなパターンbetween [24-48] hoursが「機能しない」ことは明らかです。この場合の文字クラスはと同等[248]です。

つまり-、文字クラスの定義では、パターンの数値範囲を定義していません。正規表現エンジンは、パターン内の数値を実際に「理解」しませんが、有限反復構文(例:a{3,5}3と5の間の一致a)を除きます。

範囲の定義では、代わりに文字のASCII / Unicodeエンコーディングを使用して範囲を定義します。文字0はASCIIで10進数48としてエンコードされます。9したがって、文字定義に[0-9]は、エンコードで10進数の48と57の間の値を持つすべての文字が含まれます。むしろ賢明に、設計することで、これらは文字です01、...、 9

こちらもご覧ください


別の例:AからZ

別の一般的な文字クラス定義を見てみましょう [a-zA-Z]

ASCIIの場合:

  • A= 65、Z= 90
  • a= 97、z= 122

この意味は:

  • [a-zA-Z]そして[A-Za-z]同等です
  • ほとんどのフレーバーで[a-Z]は、不正な文字範囲である可能性があります
    • ので、a(97)より、 "より大きい"であるZ(90)
  • [A-z] は合法ですが、次の6つの文字も含まれます。
    • [(91)、\(92)、](93)、^(94)、_(95)、`(96)

関連する質問


私にとっては、1桁の場合は0で始まる月を探していました。そして私はこれを使用しました([1-9] |(1 [0-2]))そしてそれは動作します。
bunjeeb 2017

2
注意すべき重要な点:このページが10に到達する前に1桁しかない数値範囲の解決策を求めている場合、機能し0[1-9]|1[0-2]ません。論理的な次のステップにそれを変更することは[1-9]|1[0-2]理解できる理由から(それが一致するためのいずれかに動作しない1だけで1011、および12)。\b(?:[0-9]|1[0-1])\bそれを防ぐために使用する必要がありました。\bさんは(境界必ず正規表現は、単語と一致する(または、このケース番号で)作る^$なかったです)。括弧は、または(|)を反対側と見なします。そして最後?:に、ブラケットを使用してサブマッチを作成しないことです。
user66001

@polygenelubricants:"1,2,3,4,5,6,7,8,9,10,17,18".match(/^(([1-9]|1[0-7])\,?)+$/g )このJS正規表現が17を超える理由は何ですか?
エダム

@edam - polygenelubricantsができた、と私はできたが、その後、我々はするだろう答えquestiを ...待ち時間が...これは質問あなたが求めているのコメント?このサイトにはrulezがあります;)新しい質問がある場合は質問してください。コメントは明確化を求めて批判し、尋ねるためのものであり、それらに応答するためのものです。
robinCTS 2018年

1
@edamああ、なるほど。あなたはなかった時間後に質問として、それを再尋ねます。それは素晴らしいことです!ただし、ここでコメントを削除することをお勧めします。
robinCTS 2018年

24

[...]構文で示される正規表現の文字クラスは、入力内の単一の文字に一致するルールを指定します。そのため、括弧内に記述するすべてのものは、単一の文字を照合する方法を指定します。

[01-12]したがって、パターンは次のように分類されます。

  • 0-1桁の0に一致
  • または、1-1、1から1の範囲の1桁に一致
  • または、2、1桁に一致2

つまり、基本的に一致するのは0、1、または2だけです。

必要な照合を行うには、01〜12の範囲の2桁を数字として照合するために、それらがテキストとしてどのように見えるかを考える必要があります。

あなたが持っている:

  • 01-09(つまり、最初の数字は0、2番目の数字は1-9)
  • 10-12(つまり、最初の数字は1、2番目の数字は0-2)

次に、そのための正規表現を記述する必要があります。これは次のようになります。

  +-- a 0 followed by 1-9
  |
  |      +-- a 1 followed by 0-2
  |      |
<-+--> <-+-->
0[1-9]|1[0-2]
      ^
      |
      +-- vertical bar, this roughly means "OR" in this context

それらを組み合わせて短い式を取得しようとすると、無効な入力に対して誤検出の一致が発生して失敗することに注意してください。

たとえば、パターン[0-1][0-9]は基本的に00-19の数字に一致しますが、これはあなたが望むものより少し多いです。

文字クラスの詳細については、明確なソースを探してみましたが、今のところ、この正規表現文字クラス用のGoogleクエリだけをお伝えできます。うまくいけば、そこにあなたを助けるためにいくつかのより多くの情報を見つけることができるでしょう。


9

これも機能します:

^([1-9]|[0-1][0-2])$

[1-9] 1と9の間の1桁に一致します

[0-1][0-2] 10〜12の2桁に一致

ここにいくつかの良い例があります


2
正確には、に[0-1][0-2]も一致し00ます。とは言っても、リンクの+1(これは私の回答で使用しました)。
polygenelubricants

2
[0-1][0-2]それは文字列が好きなことができるように慎重に解釈しなければならない000102、それは認めていない03まで09、最終的に認め1011そして12。そのための正しい正規表現は[1-9]|1[0-2]、または0*([1-9]|1[0-2])(これは最後に任意の数の先行ゼロを許可する)です。
ルイスコロラド

1

[]正規表現のsは文字クラスを示します。範囲が指定されていない場合は、暗黙的に、または範囲内のすべての文字がまとめられます。したがって、何もキャプチャしないことを除いて[abcde]、と同じ(a|b|c|d|e)です。それは、のいずれかと一致しますabcd、またはe。範囲が示すのはすべて文字のセットです。[ac-eg]「のいずれかに一致します:a; cとの間の任意の文字e;またはg」。したがって、あなたの一致は、「次のいずれかに一致します:0; 1との間の任意の文字1つまり、ちょうど1);または2

あなたの目標は、番号の範囲を指定することが明らかである:任意の数の間01122桁の数字で書かれました。この特定のケースでは、あなたがそれを一致させることができます0[1-9]|1[0-2]:いずれかの0間のいずれかの数字が続く19、あるいは1間のいずれかの数字が続く02。一般に、任意の数値範囲を同様の方法で有効な正規表現に変換できます。ただし、正規表現よりも優れたオプションや、正規表現を作成できる既存の関数またはモジュールがある場合があります。それはあなたの言語に依存します。


0

polygenelubricantsが言うように、文字クラス([]内のもの)は文字列ではなく文字と一致するため、希望するものではなく0 | 1-1 | 2を探します。


3
0|1-1|2-この表記は非常に誤解を招くものです。のようなもの0|1|2がより正確になります。
polygenelubricants 2010年

0

これを使って:

0?[1-9]|1[012]
  • 07:有効
  • 7:有効
  • 0:一致しない
  • 00:一致しない
  • 13:一致しない
  • 21:一致しない

2018年7月としてパターンをテストするには、次のコードを使用します。

/^(0?[1-9]|1[012])\/([2-9][0-9]{3})$/

(2000年1月から9999年12月の日付範囲)


私はこれを行う方法を理解しようとしていますが、0のみの3番目の条件を通過させる必要があります。
mkaatman
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.