Reputation: 1425
My program parses an XML-File which contains paths. Now I need to parse special folders like Appdata
on different Windows devices:
<entry path="C:\Users\Simon\AppData\Roaming\myprogram" />
My attempt is to change the line into:
<entry path="#{APPDATA}\myprogram" />
and parse it using a Regular Expression:
string pattern = "#{ * }"; // what does fit here?
I've read some tutorials one Regex but I just can't figure out which Regex fits here.
How can I get the content between #{
and }
using a regular Expression?
Upvotes: 0
Views: 121
Reputation: 23867
Reading your question once again, maybe it is the other way you are asking?
void Main()
{
string myXML = @"
<x>
<paths>
<entry path=""#{APPDATA}\myprogram"" />
<entry path=""#{APPDATA}\yourprogram"" />
<entry path=""#{APPDATA}\hisprogram"" />
<entry path=""C:\OtherFolder\DummyProgram"" />
<entry src=""C:\OtherFolder\DummyProgram"" />
</paths>
<Other>Other</Other>
</x>";
var appdata = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData );
XDocument doc = XDocument.Parse(myXML);
doc.Descendants("entry")
.Where(xd => xd.Attribute("path") != null &&
((string)xd.Attribute("path")).StartsWith("#{APPDATA}"))
.ToList()
.ForEach(e => {
var oldPath = (string)e.Attribute("path");
var newPath = Path.Combine(appdata, Path.GetFileName(oldPath));
e.Attribute("path").SetValue(newPath);
} );
Console.WriteLine( doc.ToString() );
}
Upvotes: 1
Reputation: 388413
Just register general placeholders which you replace, e.g.
Dictionary<string, string> placeholders = new Dictionary<string, string>
{
{ "#{APPDATA}", @"C:\Users\Simon\AppData\Roaming" },
{ "#{SYSTEM32}", @"C:\Windows\System32" }
};
string ReplacePlaceholders (string text)
{
foreach (var kv in placeholders)
{
text = text.Replace(kv.Key, kv.Value);
}
return text;
}
Used like this:
// this would come from the XML attribute
string path = @"#{APPDATA}\myprogram";
string newPath = ReplacePlaceholders(path);
Console.WriteLine(newPath); // C:\Users\Simon\AppData\Roaming\myprogram
As for actual values paths, you can also use Environment.GetFolderPath
with the Environment.SpecialFolder
enumeration to get the actual paths. But for the replacements and also other values, the answer still applies
Finally, since I wasn’t sure from your question in what direction you wanted to make these replacements, of course you can also reverse the mapping in above dictionary. I just assumed you had placeholders you wanted to replace by real paths.
Upvotes: 2
Reputation: 23867
Wouldn't it be simpler to use Linq To XML for this. I couldn't see an exact pattern in your question, but probably something like this:
void Main()
{
string myXML = @"
<x>
<paths>
<entry path=""C:\Users\Simon\AppData\Roaming\myprogram"" />
<entry path=""C:\Users\Simon\AppData\Roaming\yourprogram"" />
<entry path=""C:\Users\Simon\AppData\Roaming\hisprogram"" />
<entry path=""C:\OtherFolder\DummyProgram"" />
<entry src=""C:\OtherFolder\DummyProgram"" />
</paths>
<Other>Other</Other>
</x>";
XDocument doc = XDocument.Parse(myXML);
doc.Descendants("entry")
.Where(xd => xd.Attribute("path") != null &&
((string)xd.Attribute("path")).ToLower().Contains("appdata"))
.ToList()
.ForEach(e => {
var oldPath = (string)e.Attribute("path");
var newPath = @"#{APPDATA}\" + Path.GetFileName(oldPath);
e.Attribute("path").SetValue(newPath);
} );
Console.WriteLine( doc.ToString() );
}
Upvotes: 0
Reputation: 43768
You would want to use a match group in your regex. It would look like:
"#{(.*)}"
Then the Match.Groups property (documentation in the above link) would contain that "APPDATA" text.
This code prints "APPDATA" to the console
var matches = Regex.Matches(@"#{APPDATA}\myprogram", "#{(.*)}");
foreach (Match match in matches)
Console.WriteLine(match.Groups[1].Value);
Upvotes: 1