سؤال

أحاول تحليل سلسلة مثل ما يلي باستخدام تعبير عادي .NET:

H3Y5NC8E-TGA5B6SB-2NVAQ4E0

وإرجاع ما يلي باستخدام Split:H3Y5NC8E TGA5B6SB 2NVAQ4E0

أقوم بالتحقق من صحة كل حرف مقابل مجموعة أحرف محددة (لاحظ أن الأحرف "I" و"O" و"U" و"W" غائبة)، لذا فإن استخدام string.Split ليس خيارًا.يمكن أن يختلف عدد الأحرف في كل مجموعة، كما يمكن أن يختلف عدد المجموعات أيضًا.أنا أستخدم التعبير التالي:

([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8}-?){3}

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

(([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})-?){4}

لكن هذا لا يعمل.

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


يرجى ملاحظة أن مجموعة الأحرف لا تشمل الأبجدية بأكملها.إنه جزء من نظام تنشيط المنتج.وعلى هذا النحو، تتم إزالة أي أحرف يمكن تفسيرها عن طريق الخطأ على أنها أرقام أو أحرف أخرى.على سبيل المثالالأحرف "I" و"O" و"U" و"W" ليست موجودة في مجموعة الأحرف.

تعتبر الواصلات اختيارية نظرًا لأن المستخدم لا يحتاج إلى كتابتها في الأعلى، ولكن يمكن أن تكون موجودة إذا قام المستخدم بالنسخ واللصق.

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

المحلول 2

لقد اكتشفت الإجابة التي كنت أبحث عنها.هنا هو رمز العمل الخاص بي:

    static void Main(string[] args)
    {
        string pattern = @"^\s*((?<group>[ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})-?){3}\s*$";
        string input = "H3Y5NC8E-TGA5B6SB-2NVAQ4E0";
        Regex re = new Regex(pattern);
        Match m = re.Match(input);

        if (m.Success)
            foreach (Capture c in m.Groups["group"].Captures)
                Console.WriteLine(c.Value);
    }

نصائح أخرى

راجع للشغل، يمكنك استبدال فئة الأحرف [ABCDEFGHJKLMNPQRSTVXYZ0123456789] بفئة أحرف مطروحة أكثر قابلية للقراءة.

[[A-Z\d]-[IOUW]]

إذا كنت تريد فقط مطابقة 3 مجموعات من هذا القبيل، فلماذا لا تستخدم هذا النمط 3 مرات في التعبير العادي الخاص بك وتستخدم فقط 1، 2، 3 مجموعات فرعية تم التقاطها لتشكيل السلسلة الجديدة؟

([[A-Z\d]-[IOUW]]){8}-([[A-Z\d]-[IOUW]]){8}-([[A-Z\d]-[IOUW]]){8}

في PHP سأعود (لا أعرف .NET)

return "$1 $2 $3";

بعد الاطلاع على سؤالك والإجابات المقدمة، توصلت إلى ما يلي:

RegexOptions options = RegexOptions.None;
Regex regex = new Regex(@"([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8})", options);
string input = @"H3Y5NC8E-TGA5B6SB-2NVAQ4E0";

MatchCollection matches = regex.Matches(input);
for (int i = 0; i != matches.Count; ++i)
{
    string match = matches[i].Value;
}

نظرًا لأن "-" اختياري، فلن تحتاج إلى تضمينه.لست متأكدًا من سبب استخدامك لـ {4} في النهاية؟سيؤدي هذا إلى العثور على المطابقات بناءً على ما تريد، ثم باستخدام MatchCollection يمكنك الوصول إلى كل تطابق لإعادة بناء السلسلة.

لماذا استخدام ريجكس؟إذا كانت المجموعات مقسمة دائمًا بـ -، ألا يمكنك استخدام Split()؟

آسف إذا لم يكن هذا هو ما قصدته، ولكن السلسلة الخاصة بك تحتوي دائمًا على الواصلة التي تفصل بين المجموعات، فبدلاً من استخدام التعبير العادي، ألا يمكنك استخدام طريقة String.Split()؟

Dim stringArray As Array = someString.Split("-")

ما هي الخصائص المميزة للكتلة الصالحة؟نحن بحاجة إلى معرفة ذلك لكي نكون مفيدًا حقًا.

اقتراحي العام هو التحقق من صحة مجموعة الأحرف في الخطوة الأولى، ثم التقسيم والتحليل بطريقة منفصلة بناءً على ما تتوقعه.إذا كان هذا موجودًا في موقع ويب/تطبيق، فيمكنك استخدام التحقق من صحة ASP Regex على الواجهة الأمامية ثم تقسيمه على النهاية الخلفية.

إذا كنت تتحقق فقط من قيمة المجموعة، باستخدام قيمة المجموعة (i)، فستحصل على القيمة الأخيرة فقط.ومع ذلك، إذا كنت تريد تعداد جميع الأوقات التي تم فيها التقاط هذه المجموعة، فاستخدم group(2).captures(i).value، كما هو موضح أدناه.

system.text.RegularExpressions.Regex.Match("H3Y5NC8E-TGA5B6SB-2NVAQ4E0","(([ABCDEFGHJKLMNPQRSTVXYZ0123456789]+)-?)*").Groups(2).Captures(i).Value

مايك،

يمكنك استخدام مجموعة الأحرف التي تختارها داخل مجموعة الأحرف.كل ما تحتاجه هو إضافة معدل "+" لالتقاط جميع المجموعات.راجع إجابتي السابقة، فقط قم بتغيير [A-Z0-9] إلى ما تحتاجه (أي.[ABCDEFGHJKLMNPQRSTVXYZ0123456789])

يمكنك استخدام هذا النمط:

Regex.Split("H3Y5NC8E-TGA5B6SB-2NVAQ4E0", "([ABCDEFGHJKLMNPQRSTVXYZ0123456789]{8}+)-?")

ولكنك ستحتاج إلى تصفية السلاسل الفارغة من المصفوفة الناتجة.اقتباس من MSDN:

إذا كانت عدة تطابقات متجاورة مع بعضها البعض، فسيتم إدراج سلسلة فارغة في المصفوفة.

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