2016-02-18 3 views
2

У меня есть Dictionary<string, string>, используемый для соответствия string новым.Обработка строк на основе словаря

Dictionary<string, string> dictionary = new Dictionary<string, string>() 
{ 
    { "foo", "bar" } 
}; 

метод я использую, чтобы соответствовать string:

public static string GetValueOrKeyAsDefault(this Dictionary<string, string> dictionary, string key) 
{ 
    string value; 
    return dictionary.TryGetValue(key, out value) ? value : key; 
} 

Используется как так:

string s1 = dictionary.GetValueOrKeyAsDefault("foo"); /* s1 equals "bar" */ 
string s2 = dictionary.GetValueOrKeyAsDefault("test"); /* s2 equals "test" */ 

Теперь я хочу, чтобы соответствовать string частично и сохранить часть этой строки в соответствует одному.

/* {0} is arbitrary, could be anything else */ 
Dictionary<string, string> dictionary = new Dictionary<string, string>() 
{ 
    { "SPROC:{0}", "{0}" }, 
    { "onClick='{0}(this)'", "{0}" } 
}; 

string s1 = dictionary.SomeMethod("SPROC:my_sproc"); /* s1 equals "my_sproc" */ 
string s2 = dictionary.SomeMethod("onClick='HandleOnClick(this)'"); /* s1 equals "HandleOnClick" */ 

Я чувствую, как regex может быть путь, но я понятия не имею, как ее реализовать.

+1

Как ваш SomeMethod знает, какая часть строки соответствует? Какой результат вы пытаетесь достичь? – CodeMonkey

+1

Если '{0}' произвольно, каково правило для совпадения здесь? Если значение/ключ заканчивается ключом/значением? Или только один содержит другой? А если несколько отвечают требованиям? –

+0

@ user3387223 Результат, который я пытаюсь достичь, - это получить часть 'string'. Матч должен быть * динамическим *. –

ответ

2

Обратите внимание, что использование Dictionary<,> здесь «морально» неправильно ... Я бы использовал List<Tuple<Regex, string>>. Это морально неправильно по двум причинам: упорядочение (так что приоритет) различных значений ключа не является «фиксированным» и может быть довольно случайным, и вы не можете использовать силу Dictionary<,>: O (1) точное соответствие (TryGetValue).

Еще:

public static string SomeMethod(Dictionary<string, string> dictionary, string str) 
{ 
    foreach (var kv in dictionary) 
    { 
     var rx = new Regex(kv.Key); 

     if (rx.IsMatch(str)) 
     { 
      string replaced = rx.Replace(str, kv.Value); 
      return replaced; 
     } 
    } 

    return str; 
} 

Dictionary<string, string> dictionary = new Dictionary<string, string>() 
{ 
    { @"SPROC:(.*)", "$1" }, 
    { @"onClick='(.*)\(this\)'", "$1" }  
}; 

string replaced = SomeMethod(dictionary, "SPROC:my_sproc"); 

Обратите внимание, что вы должны использовать Regex "язык" (см (.*) и $1)

Без бесполезного Dictionary<,>:

public static string SomeMethod(IEnumerable<Tuple<Regex, string>> tuples, string str) 
{ 
    foreach (var rr in tuples) 
    { 
     if (rr.Item1.IsMatch(str)) 
     { 
      string replaced = rr.Item1.Replace(str, rr.Item2); 
      return replaced; 
     } 
    } 

    return str; 
} 

var dictionary = new[] 
{ 
    Tuple.Create(new Regex("SPROC:(.*)"), "$1"), 
    Tuple.Create(new Regex(@"onClick='(.*)\(this\)'"), "$1"), 
}; 

string replaced = SomeMethod(dictionary, "SPROC:my_sproc"); 

Как sidenote, я бы добавил ^ в начале каждого регулярного выражения и $ в конце каждого регулярного выражения, например "^SPROC:(.*)$", чтобы быть уверенным, что регулярное выражение не будет соответствовать частичным подстрокам.

+0

Спасибо, ты действительно понял, что я хотел сделать. Ты сделал это! –

Смежные вопросы