java - مفهوم - أمثلة على regular expression




Regexp جافا للتحقق من صحة كلمة المرور (6)

أعتقد أن هذا يمكن أن يفعلها أيضًا (كطريقة أبسط):

^(?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])[^\s]{8,}$

[Regex Demo]

أنا بصدد إنشاء regexp للتحقق من كلمة المرور لاستخدامها في تطبيق Java كمعلمة تكوين.

يكون التعبير العادي هو:

^.*(?=.{8,})(?=..*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$

سياسة كلمة المرور هي:

  • على الأقل 8 أحرف

  • يحتوي على رقم واحد على الأقل

  • يحتوي على واحد على الأقل من alpha char و one alpha char واحد

  • يحتوي على char واحد على الأقل ضمن مجموعة أحرف خاصة ( @#%$^ وما إلى ذلك)

  • لا يحتوي على مساحة ، أو علامة تبويب ، إلخ.

إنني في عداد المفقودين نقطة 5 فقط. أنا لست قادرة على الحصول على الاختيار regexp عن الفضاء ، علامة التبويب ، والعودة ، الخ.

يمكن أي واحد يساعدني؟


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

^(?=(.*[0-9]){%d,})(?=(.*[a-z]){%d,})(?=(.*[A-Z]){%d,})(?=(.*[^0-9a-zA-Z]){%d,})(?=\S+$).{%d,}$

لاحظ أن هذه سلسلة تنسيق وليست نمط regex نهائي. ما عليك سوى استبدال٪ d بالحد الأدنى من التكرارات المطلوبة لـ: الأرقام والحروف الصغيرة والحروف الكبيرة والحروف / الأرقام غير الكاملة وكلمة المرور بالكامل (على التوالي). الحد الأقصى للحدوث غير محتمل (إلا إذا كنت تريد حد أقصى 0 ، رفض أي من هذه الشخصيات بشكل فعال) ولكن يمكن إضافة هذه الرموز بسهولة أيضًا. لاحظ التجميع الإضافي حول كل نوع بحيث تسمح قيود الحد الأدنى / الأقصى بالمطابقة غير المتتالية. لقد عمل ذلك على إيجاد عجائب لنظام يمكننا من خلاله تحديد عدد الأحرف التي نحتاجها مركزيًا ومن ثم امتلاك موقع الويب بالإضافة إلى منصتين متنقلتين مختلفتين لجلب تلك المعلومات من أجل إنشاء نمط regex استنادًا إلى سلسلة التنسيق المذكورة أعلاه.


جميع الإجابات المعطاة مسبقًا تستخدم نفس الأسلوب (الصحيح) لاستخدام lookahead منفصل لكل متطلبات. ولكنها تحتوي على بضع أوجه قصور وحشرة هائلة ، اعتمادًا على النهاية الخلفية التي ستستخدم كلمة المرور بالفعل.

سأبدأ بالتعبير المعتاد من الإجابة المقبولة:

^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}$

أولاً وقبل كل شيء ، بما أن Java يدعم \A و \z أفضل استخدام تلك للتأكد من صحة السلسلة بأكملها ، بشكل مستقل عن Pattern.MULTILINE . لا يؤثر هذا على الأداء ، ولكنه يتجنب الأخطاء عند إعادة تدوير regexes.

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\S+$).{8,}\z

التحقق من أن كلمة المرور لا تحتوي على مسافة بيضاء ويمكن التحقق من الحد الأدنى لطولها في مسار واحد باستخدام الكل في وقت واحد عن طريق وضع متغير كمية {8,} على الاختزال \S الذي يحد من الأحرف المسموح بها:

\A(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])\S{8,}\z

إذا كانت كلمة المرور المقدمة تحتوي على مسافة ، فسيتم إجراء جميع الفحوصات ، فقط لفشل التحقق النهائي في المساحة. يمكن تجنب ذلك عن طريق استبدال جميع النقاط بـ \S :

\A(?=\S*[0-9])(?=\S*[a-z])(?=\S*[A-Z])(?=\S*[@#$%^&+=])\S{8,}\z

يجب استخدام النقطة فقط إذا كنت تريد حقًا السماح بأي حرف. وبخلاف ذلك ، استخدم فئة أحرف (negated) لتقييد regex الخاص بك فقط إلى الأحرف المسموح بها فعلاً. على الرغم من أنه لا يوجد فرق كبير في هذه الحالة ، فإن عدم استخدام النقطة عندما يكون هناك شيء آخر أكثر ملاءمة هو عادة جيدة جدًا. أرى الكثير من حالات التراجع الكارثي لأن المطور كان كسولًا جدًا لاستخدام شيء أكثر ملاءمة من النقطة.

نظرًا لوجود فرصة جيدة ، ستعثر الاختبارات المبدئية على حرف مناسب في النصف الأول من كلمة المرور ، يمكن أن يكون مقياس الكسل البطيء أكثر كفاءة:

\A(?=\S*?[0-9])(?=\S*?[a-z])(?=\S*?[A-Z])(?=\S*?[@#$%^&+=])\S{8,}\z

لكن الآن بالنسبة للقضية المهمة حقاً: لا توجد أي من الإجابات تذكر حقيقة أن السؤال الأصلي يبدو أنه كتب من قبل شخص يفكر في ASCII. ولكن في سلاسل جافا هي يونيكود. هل الأحرف غير ASCII مسموح بها في كلمات المرور؟ إذا كانت كذلك ، فليس هناك سوى مساحات ASCII غير مسموح بها ، أو يجب استبعاد كل المساحة البيضاء لـ Unicode.

بشكل افتراضي \s يتطابق مع المساحات البيضاء فقط ASCII ، بحيث يطابق \S معكوس جميع أحرف Unicode (المسافات البيضاء أم لا) وكل حروف ASCII غير بيضاء. إذا تم السماح بأحرف Unicode ولكن لم يتم تحديد مسافات Unicode ، يمكن تحديد علامة UNICODE_CHARACTER_CLASS لجعل \S استبعاد مسافة بيضاء Unicode. إذا لم يتم السماح بأحرف Unicode ، فيمكن استخدام [\x21-\x7E] بدلاً من \S لمطابقة جميع حروف ASCII التي ليست مساحة أو حرف تحكم.

الأمر الذي يقودنا إلى القضية المحتملة التالية: هل نريد السماح لشخصيات تحكم؟ الخطوة الأولى في كتابة تعبير صحيح هي تحديد ما تريده بالضبط وما لا تريده. إن الإجابة الصحيحة تقنياً بنسبة 100٪ فقط هي أن مواصفات كلمة المرور في السؤال غامضة لأنها لا تذكر ما إذا كانت نطاقات معينة من الأحرف مثل أحرف التحكم أو أحرف غير ASCII مسموح بها أم لا.


سهلة

("^ (؟ =. * [0-9]) (؟ =. * [az]) (؟ =. * [AZ]) (؟ =. * [\\ W _]) [\\ S] {8 10} $ ")

  1. (؟ = أي شيء) -> يعني إيجابية تتطلع إلى الأمام في كل سلسلة الإدخال وتأكد من كتابة هذا الشرط. عينة (؟ =. * [0-9]) -> يعني التأكد من كتابة رقم واحد في كل سلسلة. إذا لم يكتب مكتوبًا كاذبًا .
  2. (؟) أي شيء) -> (vise versa) تعني سلبيات تتطلع إلى الأمام إذا تمت كتابة شرط إرجاع false .

    إغلاق المعنى ^ (شرط) (شرط) (شرط) (شرط) [\ S] {8،10} $


مثال بسيط باستخدام regex

public class passwordvalidation {
    public static void main(String[] args) {
      String passwd = "[email protected]"; 
      String pattern = "(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}";
      System.out.println(passwd.matches(pattern));
   }
}

التفسيرات:

  • (?=.*[0-9]) يجب أن يظهر الرقم مرة واحدة على الأقل
  • (?=.*[az]) يجب أن يظهر حرف الحالة الأقل مرة واحدة على الأقل
  • (?=.*[AZ]) يجب أن يظهر حرف العلبة مرة واحدة على الأقل
  • (?=.*[@#$%^&+=]) يجب أن يحدث حرف خاص مرة واحدة على الأقل
  • (?=\\S+$) لا يسمح بالمسافة البيضاء في السلسلة بأكملها
  • .{8,} على الأقل 8 أحرف

يجب ألا تستخدم Regex معقدة بشكل مفرط (إذا كنت تستطيع تجنبها) لأنها كذلك

  • يصعب قراءتها (على الأقل لكل شخص ولكن نفسك)
  • من الصعب تمديدها
  • يصعب تصحيحه

على الرغم من أنه قد يكون هناك حمل أداء صغير في استخدام العديد من التعبيرات العادية الصغيرة ، إلا أن النقاط الموجودة أعلى من وزنه بسهولة.

سوف أقوم بتنفيذ مثل هذا:

bool matchesPolicy(pwd) {
    if (pwd.length < 8) return false;
    if (not pwd =~ /[0-9]/) return false;
    if (not pwd =~ /[a-z]/) return false;
    if (not pwd =~ /[A-Z]/) return false;
    if (not pwd =~ /[%@$^]/) return false;
    if (pwd =~ /\s/) return false;
    return true;
}




regex