मैंने कोड का एक छोटा टुकड़ा लिखा है जो रूपांतरण करता है। मुझे लगता है कि यह किसी और के लिए उपयोगी हो सकता है। मैंने रेगेक्स के balancing goup definitions के रास्ते पर बहुत कुछ सीखा है।
public static class RazorConversor
{
public static void ConvertAll(string directory)
{
string[] array = Directory.GetFiles(directory, "*.aspx", SearchOption.AllDirectories).Concat(
Directory.GetFiles(directory, "*.ascx", SearchOption.AllDirectories)).ToArray();
foreach (var fileName in array)
{
string aspxCode = File.ReadAllText(fileName);
string razorCode = ConvertToRazor(aspxCode);
File.WriteAllText(fileName, razorCode); //rename manually to update .csproj & source control
}
}
static readonly string[] DefaultNamespaces = new string[]
{
"System.Web.Helpers",
"System.Web.Mvc",
"System.Web.Mvc.Ajax",
"System.Web.Mvc.Html",
"System.Web.Routing",
"System.Web.WebPages",
};
public static string ConvertToRazor(string aspxCode)
{
return ConvertToRazor(aspxCode, DefaultNamespaces);
}
public static string ConvertToRazor(string aspxCode, string[] defaultNamespaces)
{
//namespaces
string text2 = Regex.Replace(aspxCode, @"<%@\s+Import Namespace=""(?<ns>.*?)""\s+%>",
m => defaultNamespaces.Contains(m.Groups["ns"].Value) ? null : "@using " + m.Groups["ns"].Value);
//headers
string text3 = Regex.Replace(text2, @"<%@\s(?<dir>.*?)%>", m => "@{ " + m.Groups["dir"].Value + "}"); // Preserves headers
//expressions
string text4 = Regex.Replace(text3, @"<%[=:](?<expr>.*?)%>", m =>
{
string expr = m.Groups["expr"].Value.Trim();
string cleanExpr = Regex.Replace(expr, @"(""(\\""|[^""])*"")|(@""([^""]|"""")*"")|(\([^\(\)]*(((?'Open'\()[^\(\)]*)+((?'Close-Open'\))[^\(\)]*)+)*\))", m2 => "");
return cleanExpr.Contains(' ') ? "@(" + expr + ")" : "@" + expr;
}, RegexOptions.Singleline);
//code blocks
string text5 = Regex.Replace(text4, @"<%(?<code>.*?)%>", m =>
{
string code = m.Groups["code"].Value.Trim();
Dictionary<string, string> stringLiterals = new Dictionary<string,string>();
code = Regex.Replace(code, @"(""(\\""|[^""])*"")|(@""([^""]|"""")*"")", m2 =>
{
string key = "<$" + stringLiterals.Count + "$>";
stringLiterals.Add(key, m2.Value);
return key;
});
string result = Regex.Replace(code,
@"((?<blockHeader>(else|(for|switch|foreach|using|while|if)\s*\([^\(\)]*(((?'Open'\()[^\(\)]*)+((?'Close-Open'\))[^\(\)]*)+)*\))\s*)" +
@"((?<fullBlock>{[^{}]*(((?'OpenCurly'{)[^{}]*)+((?'CloseCurly-OpenCurly'})[^{}]*)+)*})|(?<openblock>{.*))|" +
@"(?<text>((?!({|}|\s)(for|switch|foreach|using|while|if|else)(\s|{|\()).)+))",
m2 =>
{
if(m2.Value.Trim().Length == 0 || m2.Value.StartsWith("else")|| m2.Value.StartsWith("}"))
return m2.Value;
if(m2.Groups["text"].Success)
return "@{ " + m2.Value.Trim() + "}\r\n";
return "@" + m2.Value;
}, RegexOptions.ExplicitCapture | RegexOptions.Singleline);
result = Regex.Replace(result, @"<\$\d+\$>",
m2 => stringLiterals[m2.Value]);
return result;
}, RegexOptions.Singleline);
return text5;
}
}
बेशक आपने फ्रेड्रिक लुंड से प्रसिद्ध कूप सुना है: "कुछ लोग, जब किसी समस्या का सामना करते हैं, तो सोचें" मुझे पता है, मैं नियमित अभिव्यक्तियों का उपयोग करूंगा। "अब उन्हें दो समस्याएं हैं।" उपयोगिता के लिए धन्यवाद, इसे एक भंवर देने के लिए इंतजार नहीं कर सकता। –
मुझे लगता है कि दुनिया एक ऐसे उपकरण की प्रतीक्षा कर रही है जो नियमित अभिव्यक्तियों के synthax को हाइलाइट करती है। इस बीच, मुझे लगता है कि नियमित अभिव्यक्ति के बिना ऐसा करने के लिए बहुत अधिक कोड की आवश्यकता होगी। – Olmo
@ ओल्मो: मुझे [RegExr] (http://gskinner.com/RegExr/) के साथ अच्छा अनुभव मिला है। यह बहुत अच्छा है क्योंकि यह उस रेगेक्स के हिस्से को हाइलाइट करता है जो आप होवर कर रहे हैं और संदर्भ संवेदनशील सहायता प्रदान करता है। आप इसे आज़मा सकते हैं - वे डेस्कटॉप संस्करण भी प्रदान करते हैं (जिसे मैंने अभी तक उपयोग नहीं किया है)। – Oliver