如何在C#中使用Regex获取子字符串

时间:2015-10-06 14:20:37

标签: c# regex

我的程序解析包含路径的XML文件。现在我需要解析不同Windows设备上的Appdata等特殊文件夹:

<entry path="C:\Users\Simon\AppData\Roaming\myprogram" />

我的尝试是将行改为:

<entry path="#{APPDATA}\myprogram" />

并使用正则表达式解析它:

string pattern = "#{ * }"; // what does fit here?

我已经阅读了一些Regex的教程,但我无法弄清楚哪个Regex适合这里。

如何使用正则表达式在#{}之间获取内容?

4 个答案:

答案 0 :(得分:2)

只需注册您替换的常规占位符,例如

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.GetFolderPathEnvironment.SpecialFolder enumeration来获取实际路径。但对于替换和其他值,答案仍然适用

最后,由于我不确定你想要在哪个方向进行这些替换,你当然也可以在上面的字典中反转映射。我只是假设你有想要用实际路径替换的占位符。

答案 1 :(得分:1)

您希望在正则表达式中使用match group。它看起来像是:

"#{(.*)}"

然后Match.Groups属性(上面链接中的文档)将包含&#34; APPDATA&#34;文本。

此代码打印&#34; APPDATA&#34;到控制台

        var matches = Regex.Matches(@"#{APPDATA}\myprogram", "#{(.*)}");
        foreach (Match match in matches)
          Console.WriteLine(match.Groups[1].Value);

答案 2 :(得分:1)

再次阅读你的问题,也许这是你要问的另一种方式?

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() );

}

答案 3 :(得分:0)

使用Linq To XML不会更简单。我无法在你的问题中看到确切的模式,但可能是这样的:

01 def findAnagrams()
02   word_list = Hash.new([]) # I set the default value here
03   # word_list.default = Array.new
04   File.open("/home/luchen/class/words.txt").each_line do |line|
05     word = line.chomp.strip.downcase
06     word_sort = word.chars.sort.join
07     # puts word+"------"+word_sort
08     word_list[word_sort].push(word)
09     # puts word_list[word_sort]
10   end 
11   puts word_list.to_s
12 end
13 
14 findAnagrams()