2009-09-01 26 views
1

は誰かがします正規表現の式に置くことができます:
&:正規表現表現の課題は

  1. で始まる[%および%で終わる]チャンクを見つけることをそのチャンク内の
  2. ですべてのXMLの特殊文字を置き換えます。 & apos; & lt; & gt; & amp;
  3. <%#または<%後にスペースがあることを確認してください=と%前以外であるよう<% = Integer.MaxValue%>になるはずです例えば> <% =%>または<%#1%>の間にすべてのものを残します<% = Integer.MaxValue%>

源:

[% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue% > %] 

結果:

&apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%= Integer.MaxValue %> 
+4

あなたが記述ロジックは、正規表現よりも文字による文字列の文字を解析するためのより多くの仕事である」も参照してください。 – Cascabel

+0

はJefromiに同意します。これは、1つの使用をするかもしれないいくつかのコードのジョブ(ありますまたは2つの正規表現) –

答えて

2

は2つの正規表現を使用します。一般的なフォームと一致する1番目、内部の配管を処理する2番目。

XMLエンコーディングの場合、私はSystem.Securityにあるわかりにくい小さなメソッドを使用しました:SecurityElement.Escape Method。私は強調するために以下のコードでそれを完全に修飾しました。もう1つのオプションはHttpUtility.HtmlEncode methodを使用していますが、これはどこでこれを使用しているかに応じてSystem.Webへの参照を含む場合があります。

string[] inputs = { @"[% 'test' <mtd:ddl id=""asdf"" runat=""server""/> & <%= Integer.MaxValue %> %]", 
    @"[% 'test' <mtd:ddl id=""asdf"" runat=""server""/> & <%=Integer.MaxValue %> %]", 
    @"[% 'test' <mtd:ddl id=""asdf"" runat=""server""/> & <%# Integer.MaxValue%> %]", 
    @"[% 'test' <mtd:ddl id=""asdf"" runat=""server""/> & <%#Integer.MaxValue%> %]", 
}; 
string pattern = @"(?<open>\[%)(?<content>.*?)(?<close>%])"; 
string expressionPattern = @"(?<content>.*?)(?<tag><%(?:[=#]))\s*(?<expression>.*?)\s*%>"; 

foreach (string input in inputs) 
{ 
    string result = Regex.Replace(input, pattern, m => 
     m.Groups["open"].Value + 
     Regex.Replace(m.Groups["content"].Value, expressionPattern, 
      expressionMatch => 
      System.Security.SecurityElement.Escape(expressionMatch.Groups["content"].Value) + 
      expressionMatch.Groups["tag"].Value + " " + 
      expressionMatch.Groups["expression"].Value + 
      " %>" 
     ) + 
     m.Groups["close"].Value 
    ); 

    Console.WriteLine("Before: {0}", input); 
    Console.WriteLine("After: {0}", result); 
} 

結果:

Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue %> %] 
After: [% &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%= Integer.MaxValue %> %] 
Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%=Integer.MaxValue %> %] 
After: [% &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%= Integer.MaxValue %> %] 
Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%# Integer.MaxValue%> %] 
After: [% &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%# Integer.MaxValue %> %] 
Before: [% 'test' <mtd:ddl id="asdf" runat="server"/> & <%#Integer.MaxValue%> %] 
After: [% &apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%# Integer.MaxValue %> %] 

EDIT:

あなたが最終的な結果に[%%]クローズ/開口部を維持するために気にしない場合は、その後にパターンを変更します
string pattern = @"\[%(?<content>.*?)%]"; 

次に、m.Groups["open"].Valueと0の参照を削除してください。

+0

興味深いことに、ファイルから文字列を読み込んだ場合、これは機能しませんか?文字列は二重引用符( "")を除いて、使用した文字列(最初の文字列)とまったく同じです。 ? – epitka

+0

@epitka:すべてのデータが1行にあるか分割されていますか?その場合、一致しません(つまり、行間にまたがっていません)。二重引用符の二番目のセットは、@記号を使って逐語的な文字列としてコード内にエスケープするためだけにあるので、実際の入力には当然二重引用符が1つしかありません。それは問題ではないと言った。私はサンプル・データをテキスト・ファイルに置き、1行目をstring [] inputs = File.ReadAllLines(@ "c:\ temp.txt")に変更し、うまくいきました。また、File.ReadAllText(...)を使用して1つの文字列で試してみました。あなたがファイルからどのようにファイルを読み込んでいるのか、またどのように見えるのかを教えてくれますか? –

+0

Regex.Replaceステートメントの末尾にRegexOptions.Singlelineオプションを追加することができます(最後のパラメータとして追加します。これには、重複したReplaceメソッドがあります)。これにより、データが複数の行にまたがっても機能します。 –

1
private void button1_Click(object sender, EventArgs e) 
     { 
      Regex reg = new Regex(@"\[%(?<b1>.*)%\]"); 
      richTextBox1.Text= reg.Replace(textBox1.Text, new MatchEvaluator(f1)); 
     } 

     static string f1(Match m) 
     { 
      StringBuilder sb = new StringBuilder(); 
      string[] a = Regex.Split(m.Groups["b1"].Value, "<%[^%>]*%>"); 
      MatchCollection col = Regex.Matches(m.Groups["b1"].Value, "<%[^%>]*%>"); 
      for (int i = 0; i < a.Length; i++) 
      { 
       sb.Append(a[i].Replace("&", "&amp;").Replace("'", "&apos;").Replace("\"", "&quot;").Replace("<", "&lt;").Replace(">", "&gt;")); 
       if (i < col.Count) 
        sb.Append(col[i].Value); 
      } 
      return sb.ToString(); 
     } 

のTest1:

[% 'test' <mtd:ddl id="asdf" runat="server"/> & <%= Integer.MaxValue%> fdas<% hi%> 321%] 

結果:

&apos;test&apos; &lt;mtd:ddl id=&quot;asdf&quot; runat=&quot;server&quot;/&gt; &amp; <%= Integer.MaxValue%> fdas<% hi%> 321 
0

RegExを使用せずにコードが明確になると思います。私はあなたの仕様の各ラインのための別の方法(と単体テスト)を書く傾向があり、それらを一緒にチェーン。

When not to use Regex in C# (or Java, C++ etc)"