2009-09-29 3 views
2

У меня есть строки в форме: "[пользователь: fred] [приоритет: 3] Lorem ipsum dolor sit amet." где область, заключенная в квадратные скобки, является тегом (в формате [ключ: значение]). Мне нужно, чтобы иметь возможность удалить определенный тег дал это ключ, с помощью следующего метода расширения:help с тегом удаления regex

public static void RemoveTagWithKey(this string message, string tagKey) { 
    if (message.ContainsTagWithKey(tagKey)) { 
     var regex = new Regex(@"\[" + tagKey + @":[^\]]"); 
     message = regex.Replace(message , string.Empty); 
    } 
} 
public static bool ContainsTagWithKey(this string message, string tagKey) { 
    return message.Contains(string.Format("[{0}:", tagKey)); 
} 

только тег с указанным ключом должны быть удалены из строки. Мое регулярное выражение не работает, потому что оно глупо. Мне нужна помощь, чтобы написать его правильно. Альтернативно, реализация без регулярного выражения приветствуется.

ответ

1

Если вы хотите сделать это без регулярного выражения, это не сложно. Вы уже ищете конкретный ключ тега, поэтому вы можете просто искать «[» + tagKey, затем искать оттуда для закрытия «]» и удалять все между этими смещениями. Что-то вроде ...

int posStart = message.IndexOf("[" + tagKey + ":"); 
if(posStart >= 0) 
{ 
    int posEnd = message.IndexOf("]", posStart); 
    if(posEnd > posStart) 
    { 
     message = message.Remove(posStart, posEnd - posStart); 
    } 
} 

Это лучше, чем решение Regex? Поскольку вы ищете только определенный ключ, я думаю, что это, вероятно, на простоте. Я люблю Regexes, но они не всегда являются самым ясным ответом.

Edit: Другой причина решения IndexOf() можно рассматривать как лучше, что это означает, что есть только одно правило для нахождения начала тега, в то время как исходный код использует Contains() который ищет что-то вроде ' [tag: ', а затем использует регулярное выражение, которое использует немного другое выражение для замещения/удаления. Теоретически вы можете иметь текст, который соответствует одному критерию, но не другому.

+0

Похоже, что исходный вопрос пытается использовать escape-код '' или '' 'внутри тега. –

+0

Я получил вариацию этого, потому что оказалось, что мне нужны другие методы расширения для других вещей (например: Словарь <строка, строка> GetTags (это сообщение m), строка GetTagValue (это сообщение m, string tagKey) и т. Д. ..). Рефакторинг означал, что нет необходимости в регулярных выражениях. – grenade

+0

@Drew Noakes: Я не думаю, что 'Regex (@ "\\ [" + tagKey + @ ": [^ \\]]"); делает то, что вы думали (может быть, не то, что думала граната!). Если вы представляете, что tagKey говорит «Zippy», регулярное выражение становится «\\ [Zippy: [^ \\]]», что означает «соответствие Zippy, за которым следует двоеточие, за которым следует один символ, который не является«] ». (Или, как вы отметили в своем ответе, вы можете положить + на конце, чтобы он соответствовал одному или нескольким символам, которые не являются «]».) Но он не делает ничего умного в том, чтобы избегать экранированных скобок, насколько я может работать (используя мой синтаксический анализатор регулярных выражений ...). – AAT

3

Я знаю, что есть гораздо больше многофункциональных инструментов, но мне нравится простота и чистота Code Architects Regex Tester (иначе YART: еще один тестер для регулярных выражений). Показывает группы и захваты в виде дерева, довольно быстро, очень мало, с открытым исходным кодом. Он также генерирует код в C++, VB и C# и может автоматически выходить из режима или повторно указывать регулярные выражения для этих языков. Я сбрасываю его в папке с инструментами VS (C: \ Program Files \ Microsoft Visual Studio 9.0 \ Common7 \ Tools) и устанавливаю для него пункт меню в меню «Инструменты» с помощью «Инструменты»> «Внешние инструменты», поэтому я могу быстро его запустить изнутри VS ,

Regexes может быть очень сложно писать иногда, и я знаю, что это действительно помогает тестировать регулярное выражение и видеть результаты по мере их поступления.

alt text http://www.dotnet2themax.com/blogs/fbalena/content/binary/RegexTester1.gif

Еще один очень популярный (но не бесплатно) вариант Regex Buddy.

1

Попробуйте вместо этого:

new Regex(@"\[" + tagKey + @":[^\]+]"); 

Единственное, что я изменил в том, чтобы добавить + к [^\] шаблону, а это означает, что вы подходите один или несколько символов, которые не обратной косой черты.

1

Я думаю, что это регулярное выражение вы ищете:

string regex = @"\[" + tag + @":[^\]+]\]"; 

Кроме того, вам не нужно делать отдельную проверку, чтобы увидеть, если есть теги этого типа. Просто замените регулярное выражение; если совпадений нет, возвращается исходная строка.

public static string RemoveTagWithKey(string message, string tagKey) { 
    string regex = @"\[" + tag + @":[^\]+]\]"; 
    return Regex.Replace(message, regex, string.Empty); 
} 

Вы, кажется, пишете метод расширения, но я написал это как статический метод утилиты, чтобы все было просто.