如何在c#中使用正则表达式获得子字符串
本文关键字:正则表达式 字符串 | 更新日期: 2023-09-27 18:16:12
程序解析一个包含路径的xml文件。现在我需要解析不同Windows设备上的特殊文件夹,如Appdata
:
<entry path="C:'Users'Simon'AppData'Roaming'myprogram" />
我试着把这行改成:
<entry path="#{APPDATA}'myprogram" />
并使用正则表达式解析它:
string pattern = "#{ * }"; // what does fit here?
我读过一些关于正则表达式的教程,但我就是不知道哪个正则表达式适合这里。
如何使用正则表达式获得#{
和}
之间的内容?
只需注册一般占位符,例如
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;
}
像这样使用:
// this would come from the XML attribute
string path = @"#{APPDATA}'myprogram";
string newPath = ReplacePlaceholders(path);
Console.WriteLine(newPath); // C:'Users'Simon'AppData'Roaming'myprogram
对于实际值路径,您也可以使用Environment.GetFolderPath
和Environment.SpecialFolder
枚举来获得实际路径。但是对于替换和其他值,答案仍然适用
最后,因为我不确定从你的问题中你想要在哪个方向进行这些替换,当然你也可以在上面的字典中反向映射。我只是假设您有想用实际路径替换的占位符。
您可能希望在正则表达式中使用匹配组。它看起来像:
"#{(.*)}"
然后是Match。Groups属性(上面链接中的文档)将包含"APPDATA"文本。
这段代码将"APPDATA"打印到控制台
var matches = Regex.Matches(@"#{APPDATA}'myprogram", "#{(.*)}");
foreach (Match match in matches)
Console.WriteLine(match.Groups[1].Value);
再次阅读你的问题,也许这是你问的另一种方式?
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() );
}
使用Linq to XML不是更简单吗?我在你的问题中没有看到一个确切的模式,但可能是这样的:
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() );
}