2010-12-03 25 views
4

Iは1から50包括的に任意の数と一致します正規表現を探しています。これまでのところ、私は例を発見したが、彼らはすべての文字列が、私にはしたくない小数点を含むことができます。だから1,13,24,50はOKですが、1.などはそうではありません。私は使用できるREGEXPはありますか?事前に正規表現

おかげで、 ティム

答えて

6

はこのお試しください:

/^(?:[1-9]|[1-4][0-9]|50)$/ 

UPDATE:

を今、私は質問は、MySQLを参照するように更新されている参照のこと、これはかなりのものに変更されます。上記の正規表現は、MySQLでサポートされていない非キャプチャの括弧を使用しています。しかしそれはまた質問をする。あなたは本当に正規表現を使ってこの問題を解決すべきでしょうか?私たちは本当にあなたが1と50の間でなければならない、あなたの番号を格納しているかを見ている彼らがvarcharのか?彼らはintのか?私は両方の方法でそれを解決する方法を示します。まず私は、インデックスでテストテーブルを設定します:

create table regextest (
    id int unsigned primary key auto_increment, 
    varchar_number varchar(5) not null, 
    int_number int not null, 
    index(varchar_number), 
    index(int_number) 
) engine=innodb; 

今、私たちのすべてのエッジケースがカバーされていることを確認すること、その中にいくつかのテストデータを置く:

insert into regextest (varchar_number, int_number) 
    values ('0', 0), ('1', 1), ('35', 35), ('49', 49), ('50', 50), ('51', 51); 

そして今、ここではそのクエリがありますあなたの番号がvarchar_number列内の文字列として格納されていると仮定し、あなたの問題を解決します:

mysql> select * from regextest where varchar_number rlike '^([1-9]|[1-4][0-9]|50)$'; 
+----+----------------+------------+ 
| id | varchar_number | int_number | 
+----+----------------+------------+ 
| 2 | 1    |   1 | 
| 3 | 35    |   35 | 
| 4 | 49    |   49 | 
| 5 | 50    |   50 | 
+----+----------------+------------+ 
4 rows in set (0.00 sec) 

これは動作しますが、それはuのことができないので、それは大規模なデータセットに対してうまく機能しますインデックスが存在していてもそのインデックスがあります。 MySQLはテーブルのすべての行に対して正規表現を1回実行する必要があります。 1と50の間にあなたの番号がint_number列にint sと保存したとします。

mysql> select * from regextest where int_number between 1 and 50; 
+----+----------------+------------+ 
| id | varchar_number | int_number | 
+----+----------------+------------+ 
| 2 | 1    |   1 | 
| 3 | 35    |   35 | 
| 4 | 49    |   49 | 
| 5 | 50    |   50 | 
+----+----------------+------------+ 
4 rows in set (0.00 sec) 

このクエリは、インデックスを使用することができ、さらに読みやすく、保守性が高いため、パフォーマンスが向上します。すべて勝ちます。

ある
+0

こんにちは、ご意見ありがとうございます。私はMySQLで次のことを試しています:1 REGEXP '/ ^(?:[1-9] | [1-4] [0-9] | 50)$ /'を選択してください。反復演算子オペランドはregexpから無効です。私はこれがバックスラッシュをエスケープしないためかもしれないと思っていますが、私は/の代わりに//しようとしましたが、まだ動作しませんでした。 – Tim

+0

@Tim:おそらく '(?:...)'の構文で、キャプチャしていないグループが導入されています。 MySQLはそれをサポートしておらず、 '? 'を反復演算子として扱うように思えますが、繰り返しは何もありません。 '(?:...)'を普通のかっこ '(...)'に置き換えると、うまくいくはずです。 –

+0

ありがとう、私は/ ^(([1-9] | [1-4] [0-9] | 50)$ /)を試しましたが、正しい数字と一致しません。 – Tim

4
'^(0?\d|[1-4]\d|50)$' 

  • 入力(0が先行する任意)単一の数字が続く
  • 、または任意の続く1-4続い
  • の開始数字、または
  • が続いた後、私たちは入力の終わりを見ていることを確認します。

編集:上記は、あなたが本当に望ましくない0(および00)を許可します。だから、あなたが本当にとにかく許さ先行ゼロを望んでいなかったと仮定すると:

'^([1-9]|[1-4]\d|50)$' 

は編集:OPの後のコメントは、これはMySQLのためのものであることを示したよう、私はパターンを指定するための構文を変更しました。

+2

これは許可されていない '0'にマッチします。 – Asaph

+0

@Asaphありがとうございます!ありがとう。修正を示すために編集しました。 – Phrogz

+0

ありがとうございます... MySQLは上記と同じnon-repeatエラーを返します... – Tim

1

^([1-9] | [1-4] [0-9] | 50)Perl6::Rulesと$

+0

1〜9 OR 10〜49 OR 50 –

+0

ありがとうございました。しかしながら、これは例1を可能にします。 – Tim

+0

@Tim上記のコメントが「それは ''を許している」という意味なら、あなたは間違っています。あなたのコメントが「それが '1'」を許すことを意味するならば、これはあなたが明示的にマッチしなければならないと明言したものです。上記のパターンは私にとってはうまく見えます。 – Phrogz

0

"不正行為":

/ (\d+) { 1 <= $1 && $1 <= 50 or fail }/

やPerl 5.10で最大、

/(\d+)(?(?{1>$1||50<$1})(*FAIL))/ 
+0

またはPerl5: '/ ^(\ d +)$(?{?{1} $ 1 || 50 <$ 1})/ x' – tchrist

+0

@tchrist:ありがとうございました。 – ephemient

0

この1

([0-4]{1}[0-9]{0,1}[.]{0,1}[0-9]{0,2}|50) 

はFoのを行いますしてみてくださいお待ちください

45.00 - Match 
4  - Match 
78 - Not Match 
51 - Not Match 
21.25 - Match 
+0

3つの問題:(1)OPは小数点と一致させたくないと答えました。 (2)彼はまた、数字は「0」または「00」ではないと言っています。あなたの正規表現は両方とも一致します。 (3)あなたの数量化が必要です。 '{0,2}'は大丈夫ですが '{0,1}'は '?'と書かれ、 '{1}'は削除されるべきです。それは、とにかくやることを正規表現エンジンに伝えることです。アタッチされているアトムの1つに正確にマッチします。 –