سؤال

أحتاج إلى مطابقة حقل عرض ثابت على تخطيط ملف مع تعبير منتظم. الحقل هو رقم رقمي / عدد صحيح، دائما أربعة أحرف ويتم تضمينها في نطاق 0..1331. عندما يكون الرقم أصغر من 1000، تمتلئ السلسلة بأصفار الأصفار اليسرى. لذلك كل هذه الأمثلة صالحة:

  • 0000
  • 0001
  • 0010
  • 1000
  • 1331

ولكن يجب أن يكون ما يلي ليس قبلت:

  • 1
  • 01
  • 10
  • 100
  • 4759

سيكون من الرائع أن أمكن هذا القيد فقط مع Regex. بعد اللعب قليلا، أسفرت عن التعبير \0*[0-1331]\. وبعد المشكلة هي أنه لا يقيد الحجم إلى أربعة أحرف. بالطبع يمكنني القيام به \000[0-9]|00[10-99]|0[100-999]|[1000-1331]\ لكنني أرفض استخدام شيء سيء للغاية. هل يمكن لأي شخص أن يفكر في أفضل طريقة؟

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

المحلول

تعبير منتظم ليس هو الحل كل مشكلة واحدة. سيكون نصيحتي أن تفعل شيئا مثل:

boolean isValidSomethingOrOther (string):
    if string.length() != 4:
        return false
    for each character in string:
        if not character.isNumeric():
            return false
    if string.toInt() > 1331:
        return false
    return true

اذا أنت يجب استخدم Regex، لا حرج في الحل الخاص بك ولكن من المحتمل أن أستخدم البديل التالي (فقط بناء على فهمي لإعادة المحركات وكيف يعملون):

^0[0-9]{3}|1[0-2][0-9]{2}|13[0-2][0-9]|133[01]$
  • المقطع الأول يطابق 0000-0999.
  • المباريات الثانية 1000-1299.
  • المباريات الثالثة 1300-1329.
  • المباريات النهائية 1330 و 1331.

تحديث:

فقط على تعليق الأناقة، هناك العديد من أشكال الأناقة التي تكون بها Regexes واحدة. يمكنك أيضا تحقيق الأناقة فقط من خلال تجريد التحقق من الصحة إلى وظيفة منفصلة أو ماكرو ثم اتصل به من التعليمات البرمجية الخاصة بك:

if isValidSomethingOrOther(str) ...

أين SomethingOrOther هو كائن أعمال ملموسة. يتيح لك ذلك تغيير فكرتك عن كائن صالحا بسهولة، حتى باستخدام Regex كما تريد أو أي اختبارات أخرى تعتبر مناسبة (مثل وظيفتي أعلاه).

يتيح لك ذلك تلبية أي تغييرات أسفل الخط مثل متطلبات أن هذه الكائن يجب أن يكون الآن أرقام أولية.

أنا متأكد من أنني يستطع اكتب "Prime-number-your-1332" regex. أنا متأكد أيضا أنا لن أفعل تريد ل - أفضل رمز أنه كدالة (أو طاولة بحث عن السرعة الخام)، خاصة وأن Regex من المرجح أن تبدو على الأرجح:

^2|3|5|7| ... |1327$

على أي حال.

نصائح أخرى

يبدو أن هذا سهل للغاية، هل أفهم المشكلة بشكل صحيح؟

\[01][0-9]{3}\

أنا لا أعرف ماذا .. يعني، عدد صحيح في النطاق؟ يجب أن تكون ممرضا أو شيء من هذا.

يبدو أن هذا يعمل بالطريقة التي تريدها بالنسبة لي:

In [3]: r = re.compile(r'[01][0-9]{3}')

In [4]: r.match('0001')
Out[4]: <_sre.SRE_Match object at 0x2fa2d30>

In [5]: r.match('1001')
Out[5]: <_sre.SRE_Match object at 0x2fa2cc8>

In [6]: r.match('2001')

In [7]: r.match('001')

In [8]: 
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top