2012-07-26 108 views
2

正在循環訪問C#關鍵字數組,併爲每個關鍵字應用正則表達式。 (我工作的語法高亮顯示。)正則表達式 - 在某些情況下不起作用

我只是想匹配,如果:

  • 關鍵字是上線的第一個字字符前面就是 一個空格,句號或一個開括號

    AND

  • 關鍵字後的字符是空格,句號或開放 括號。

這就是我想出了:

foreach (string keyword in keyWords) 
    { 
     regex = new Regex(@"(?<=[\s\.(])" + keyword + @"(?=[\s\.(])"); 
     foreach (Match match in regex.Matches(code)) 
     { 
      code = code.Replace(match.Value, "<span class='keyword'>" + match.Value + "</span>"); 
     } 
    } 

那麼,在下面的文本的情況下:

「的foreach(字符串s在SS){}」

單詞「foreach」匹配,但也有關鍵字「in」嵌套int字「字符串」匹配 - 但這不好,因爲前後的字符不符合標準。

有趣的是,在下面的文本的情況下:

「xforeachx(字符串s在SS){}」

單詞 「的foreach」 不匹配。

那麼爲什麼「字符串」中的「in」匹配而不是第二個示例中的「foreach」?我錯過了什麼?

謝謝!

+1

我相信你需要避開括號。當你想直接使用它們時,你必須表示'\('或'\)' – 2012-07-26 20:37:19

+0

你正在使用正則表達式匹配行內,然後恢復到一個字符串替換?爲什麼不使用Regex.Replace? – 2012-07-26 20:45:40

+0

@BradChristie我需要在替換中包含實際的關鍵字。不知道如何用Regex.Replace做到這一點。 – Rivka 2012-07-26 20:48:44

回答

1

以下是我在註釋中引用的一個非常簡單的演示:

StringBuilder sb = new StringBuilder(); 
sb.AppendLine("using System;"); 
sb.AppendLine(); 
sb.AppendLine("namespace Foo.Bar"); 
sb.AppendLine("{"); 
sb.AppendLine("\tpublic class Baz"); 
sb.AppendLine("\t{"); 
sb.AppendLine("\t\tpublic static void Main()"); 
sb.AppendLine("\t\t{"); 
sb.AppendLine("\t\t\tString[] a = new[]{\"foo\",\"bar\",\"baz\"};"); 
sb.AppendLine("\t\t\tforeach (var b in a) Console.WriteLine(b);"); 
sb.AppendLine("\t\t}"); 
sb.AppendLine("\t}"); 
sb.AppendLine("}"); 

Console.Write(sb.ToString()); 
Console.WriteLine(); 

String[] keywords = new String[]{ 
    "using", "namespace", "for", "if", "else", "foreach" 
}; 
String code = sb.ToString(); 
foreach (String keyword in keywords){ 
    String pattern = @"(?<=^|[\s\.\(])(" + Regex.Escape(keyword) + @")(?=[\s\.\)])"; 
    String replacement = "<span class='keyword'>$1</span>"; 
    code = Regex.Replace(code, pattern, replacement); 
} 
Console.WriteLine(code); 

,導致:

<span class='keyword'>using</span> System; 

<span class='keyword'>namespace</span> Foo.Bar 
{ 
    public class Baz 
    { 
    public static void Main() 
    { 
     String[] a = new[]{"foo","bar","baz"}; 
     <span class='keyword'>foreach</span> (var b in a) Console.WriteLine(b); 
    } 
    } 
} 

這是我認爲你以後。我使用靜態正則表達式方法,但你可以重構它你想要的。有些事情,我想指出的:

  • 我強烈建議使用Regex.Escape當你在你沒有構建自己的正則表達式語句的中間插入值。即使關鍵字只是字母,稍後的一些更改也可能會使其失效。比對不起更安全。
  • 如果您打算使用正則表達式來查找關鍵字,也可以用它來替換它。這確保瞭如果發現(並且是關鍵字)「for」被認爲是那的實例(用外觀(前|後)驗證被替換而不是在字符串中找到的「for」的偏離(可能它們具有變量名爲foreshadow - 誰知道。
  • 我稍微修改了您的後視圖,以包含^|,這意味着匹配行的開頭或類中找到的內容。
  • 我還稍微修改了您的模式以包含捕獲組,以便替換可以找到某些東西。
+0

使用靜態正則表達式很好,因爲至少它們 – usr 2012-07-26 21:04:01

+0

另外,對IDEOne – 2012-07-26 21:05:38

+0

@Rivka Brad上面的一個(有例外情況稍作修改)[工作示例](http://ideone.com/2CHvf),更改第二個項目符號以使用在「字符串」中的「in」被改變,即使它不是匹配的「in」,因爲**是爲什麼**她的代碼被破壞了。 – 2012-07-26 21:09:32

相關問題