2009-09-29 70 views
2

我有形式的字符串:“[用户:弗雷德] [优先:3]洛雷姆ipsum dolor坐amet。”用方括号括起来的区域是一个标签(格式为[key:value])。我需要能够删除特定的标签给它在以下方面扩展方法的关键:帮助与标记删除正则表达式

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); 
    } 
} 

这是否比正则表达式的解决方案更好?既然你只是在寻找一个特定的关键,我认为这可能是简单的理由。我喜欢Regexes,但它们并不总是最明确的答案。

编辑:另一个原因的IndexOf()解决方案可以被看作是更好的是,它意味着对查找标签开始只有一个规则,而原来的代码使用Contains()其搜索类似' [tag:',然后使用正则表达式来使用一个稍微不同的表达式来进行替换/移除。理论上你可以有符合一个标准但不符合其他标准的文本。

+0

它看起来像原来的问题是试图迎合标签内的['或']'标签。 – 2009-09-29 11:59:28

+0

我结束了这个变化,因为它证明我需要更多的扩展方法来处理其他的东西(例如:Dictionary GetTags(this message m),string GetTagValue(this message m,string tagKey)等。 ..)。重构意味着不需要正则表达式。 – grenade 2009-09-29 12:10:23

+0

@Drew Noakes:我不认为'正则表达式(@“\\ [”+ tagKey + @“:[^ \\]]”);'正在做你认为的事情(也许不是什么手榴弹的想法!)。如果你认为tagKey是“Zippy”,那么正则表达式变成'\\ [Zippy:[^ \\]]',意思是“匹配Zippy后跟一个冒号,后面跟一个不是”的字符]。 (或者正如你在答案中提到的那样,你可以在最后加一个+使其与一个或多个不是“]”的字符相匹配。)但是,就我而言,避免转义括号不会做任何聪明的事情可以解决(使用我的mental regex解析器...)。 – AAT 2009-09-29 12:34:09

3

我知道那里有更多功能丰富的工具,但我喜欢Code Architects Regex Tester(又名YART:又一个正则表达式测试仪)的简单性和清洁度。在树视图中显示组和捕获,相当快,非常小,开源。它还可以在C++,VB和C#中生成代码,并且可以自动转义或使用这些语言的正则表达式。我将它转储到我的VS工具文件夹(C:\ Program Files \ Microsoft Visual Studio 9.0 \ Common7 \ Tools)中,并使用工具>外部工具在工具菜单中设置一个菜单项,以便从VS内部快速启动它。

正则表达式可能真的很难写,有时候我知道它确实有助于测试正则表达式并随时查看结果。

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); 
} 

你似乎正在编写一个扩展方法,但我把它写成静态工具方法来保持简单。