C # Regex: كيف يمكنني استبدال الرموز بالسلاسل التي تم إنشاؤها في وقت التشغيل؟

StackOverflow https://stackoverflow.com/questions/1869567

سؤال

بالنظر إلى سلاسل الإدخال و Regex التالية:

const string inputString = "${Principal}*${Rate}*${Years}";
const string tokenMatchRegexString = @"\${([^}]+)}";

كيف يمكنني استبدال كل رمز رمزي (IE $ {Principal}، $ {rate}، و {years} $ {}) مع قيمة العودة لوظيفة "استبدال"؟

private static string ReplaceToken(string tokenString)
{
    switch (tokenString)
    {
        case "Principal":
            return GetPrincipal();
        case "Rate":
            return GetRate();
        case "Years":
            return GetYears();
        default:
            throw new NotImplementedException(String.Format("A replacment for the token '{0}' has not been implemented.", tokenString));
    }
}

private static string GetPrincipal()
{
    throw new NotImplementedException();
}

private static string GetRate()
{
    throw new NotImplementedException();
}

private static string GetYears()
{
    throw new NotImplementedException();
}
هل كانت مفيدة؟

المحلول

يحتوي Regex على التحميل الزائد الذي يأخذ matchevaluator. المدخلات هي تطابق، ويعيد سلسلة. ستكون قيمة المباراة في هذه الحالة هي الرمز المميز بالكامل، بحيث يمكنك إنشاء Shim الذي يستخرج القيمة (تقوم بالفعل بالتقاطه ضمن Regex الخاص بك) ويتكيف مع الطريقة التي نشرتها.

Regex.Replace(inputString,
              tokenMatchRegexString,
              match => TokenReplacement(match.Groups[1].Value));

نصائح أخرى

إذا كان لديك حقا عددا صغيرا من الرموز الرموز ليحل محل أنك تعرف في وقت مبكر، يمكنك استخدام string.Replace() فقط استبدال الرموز واحد تلو الآخر. هذه التقنية البسيطة يمكن أن تعمل، ولكن لديها عيوب. إنه غير قابل للتوسيع بشكل خاص، يمكن أن يؤدي إلى سلاسل وسيطة (رمادية)، ويمكن أن تؤدي أيضا إلى رمز مربك.

إذا كنت تتوقع أن يكون لديك العديد من الرموز الرموز المختلفة ولديها قواعد مطابقة متسقة، يمكنك استخدامها Regex.Replace() الذي يأخذ أ MatchEvaluator مندوب - وظيفة أساسا تقبل تطابق تعبير منتظم وإرجاع سلسلة لاستبدال المباراة معها. فائدة استخدام Replace() الزائد الذي يأخذ MatchEvaluator هو أنه يساعد في تجنب إنشاء الأوتار الوسيطة التي تستخدمها للتو لاستبدال المباراة التالية. من الجيد أيضا إعادة استخدام فصول .NET المدمجة، بدلا من المتداول بنفسك.

أخيرا، إذا كان لديك متطلبات تطابق / استبدال معقدة حقا، فيمكنك استخدام المكتبات مثل stringtemplate. للقيام بتوسيع قالب أكثر تعقيدا واستبدال المباراة.

إليك مثال على استخدام Regex.Replace() يتصل:

const string inputString = "${Principal}*${Rate}*${Years}";
const string tokenMatchRegexString = @"\${([^}]+)}";

var rex = new Regex( tokenMatchRegexString );
MatchEvaluator matchEval = match => TokenReplacement( match.Groups[1].Value );

rex.Replace( inputString, matchEval );

لا إعادة اختراع العجلة. أنا أستعمل stringtemplate. (إصدار C #) عند القيام بأشياء مثل هذا.

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