سؤال

أبحث عن تعبير منتظم يتوافق مع أي رقم من 1 إلى 50 شاملة. حتى الآن ، لقد وجدت أمثلة لكنها تسمح جميعًا للسلسلة باحتواء نقطة عشرية ، والتي لا أريد تضمينها. لذلك 1،13،24،50 على ما يرام ولكن 1. ، وما إلى ذلك ليست كذلك. هل هناك regexp يمكنني استخدامه؟

شكرا مقدما ، تيم

هل كانت مفيدة؟

المحلول

جرب هذا:

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

تحديث:

الآن بعد أن رأيت السؤال قد تم تحديثه للإشارة إلى 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)

يعمل هذا ولكنه سيؤدي أداءً سيئًا على مجموعات البيانات الكبيرة لأنه لا يمكنه استخدام فهرس حتى لو كان هناك واحد. يجب على MySQL تشغيل التعبير العادي مرة واحدة لكل صف في الجدول. لنفترض تم تخزين أرقامك بين 1 و 50 intS في int_number عمودي. يمكنك ببساطة القيام بذلك:

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?\d|[1-4]\d|50)$'

هذا هو:

  • بداية الإدخال
  • يليه رقم واحد (اختياري يسبقه 0) ، أو
  • تليها 1-4 تليها أي رقم ، أو
  • تليها 50
  • ثم تأكد من أن نرى نهاية المدخلات.

يحرر: ما سبق يسمح 0 (و 00) الذي لا تريده بالتأكيد. لذا ، على افتراض أنك لا تريد حقًا السماح للأصفار الرائدة على أي حال:

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

يحرر: نظرًا لأن تعليقات OP اللاحقة تشير إلى أن هذا مخصص لـ MySQL ، فقد قمت بتغيير بناء الجملة لتحديد النمط.

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

جرب هذه

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

سوف تفعل المتابعة

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

"الغش" مع Perl6 :: القواعد:

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

أو في بيرل 5.10 وما فوق ،

/(\d+)(?(?{1>$1||50<$1})(*FAIL))/
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top