C#复杂的正则表达式

时间:2010-01-11 20:38:57

标签: c# regex

嘿伙计们,感谢您提供的所有帮助。我需要一些远远超出我所知的正则表达式帮助。

我有一个带有文件名的列表框,例如3123~101,一个带有1行文本的分隔文件。我需要在文本文件中最后一个“ - ”之前的最后一个“\”后面的Regex。结尾可能包含一个前缀### {#### - 004587} .txt~公式是{### +〜#-1。

档案名称: 3123〜101 所以例1: 3123 | X:目录\路径\指南| PRE0 {0442-0500}的.txt

结果: X:\目录\路径\目录\ Pre00542.txt

档案名称: 3123〜101 所以例1: 3123 | X:目录\路径\指南| 0 {0442-0500}的.txt

结果: X:\目录\路径\目录\ 00542.txt

4 个答案:

答案 0 :(得分:3)

根据您的示例,我创建了以下正则表达式:

\|(.)(.*)\|(.*)\{\d{2}(\d{2})\-(\d{2}).*(\..*)

结果应如下:

group1 + "\\" + group2 + "\\" + group3 + group5 + group4 + group6

如果您不满意,可以随时自行调整here


编辑:

记住我关于命名组的事后:

\|(?<drive>.)(?<path>.*)\|(?<prefix>.*)\{\d{2}(?<number2>\d{2})\-(?<number1>\d{2}).*(?<extension>\..*)

drive + "\\" + path + "\\" + prefix + number1 + number2 + extension

答案 1 :(得分:2)

public static string AdjustPath(string filename, string line)
{
  int tilde = GetTilde(filename);

  string[] fields = Regex.Split(line, @"\|");

  var addbackslash = new MatchEvaluator(
    m => m.Groups[1].Value + "\\" + m.Groups[2].Value);
  string dir = Regex.Replace(fields[1], @"^([A-Z]:)([^\\])", addbackslash);

  var addtilde = new MatchEvaluator(
    m => (tilde + Int32.Parse(m.Groups[1].Value) - 1).
           ToString().
           PadLeft(m.Groups[1].Value.Length, '0'));

  return Path.Combine(dir, Regex.Replace(fields[2], @"\{(\d+)-.+}", addtilde));
}

private static int GetTilde(string filename)
{
  Match m = Regex.Match(filename, @"^.+~(\d+)$");

  if (!m.Success)
    throw new ArgumentException("Invalid filename", "filename");

  return Int32.Parse(m.Groups[1].Value);
}

按以下方式拨打AdjustPath

public static void Main(string[] args)
{
  Console.WriteLine(AdjustPath("3123~101", @"3123|X:directory\Path\Directory|Pre0{0442-0500}.txt"));
  Console.WriteLine(AdjustPath("3123~101", @"3123|X:directory\Path\Directory|0{0442-0500}.txt"));
}

输出:

X:\directory\Path\Directory\Pre00542.txt
X:\directory\Path\Directory\00542.txt

如果您想将输出写入文件,请使用

public static void WriteAdjustedPaths(string inpath, string outpath)
{
  using (var w = new StreamWriter(outpath))
  {
    var r = new StreamReader(inpath);
    string line;
    while ((line = r.ReadLine()) != null)
      w.WriteLine("{0}", AdjustPath(inpath, line));
  }
}

您可以使用

调用它
WriteAdjustedPaths("3123~101", "output.txt");

如果您想要List<String>而不是

public static List<String> AdjustedPaths(string inpath)
{
  var paths = new List<String>();

   var r = new StreamReader(inpath);
   string line;
   while ((line = r.ReadLine()) != null)
     paths.Add(AdjustPath(inpath, line));

   return paths;
}

为了避免重复逻辑,我们应该根据新函数定义WriteAdjustedPaths

public static void WriteAdjustedPaths(string inpath, string outpath)
{
  using (var w = new StreamWriter(outpath))
  {
    foreach (var p in AdjustedPaths(inpath))
      w.WriteLine("{0}", p);
  }
}

Linq可以简化语法。请参阅C# File Handling

答案 2 :(得分:1)

gbacon的答案略有不同,也适用于旧版本的.Net:

    static void Main(string[] args)
    {
        Console.WriteLine(Adjust("3123~101", @"3123|X:directory\Path\Directory|Pre0{0442-0500}.txt"));
        Console.WriteLine(Adjust("3123~101", @"3123|X:directory\Path\Directory|0{0442-0500}.txt"));
    }

    private static string Adjust(string name, string file)
    {
        Regex nameParse = new Regex(@"\d*~(?<value>\d*)");
        Regex fileParse = new Regex(@"\d*\|(?<drive>[A-Za-z]):(?<path>[^\|]*)\|(?<prefix>[^{]*){(?<code>\d*)");

        Match nameMatch = nameParse.Match(name);
        Match fileMatch = fileParse.Match(file);

        int value = Convert.ToInt32(nameMatch.Groups["value"].Value);

        int code = Convert.ToInt32(fileMatch.Groups["code"].Value);
        code = code + value - 1;

        string drive = fileMatch.Groups["drive"].Value;
        string path = fileMatch.Groups["path"].Value;
        string prefix = fileMatch.Groups["prefix"].Value;

        string result = string.Format(@"{0}:\{1}\{2}{3:0000}.txt",
            drive, 
            path,
            prefix, 
            code);

        return result;
    }

答案 3 :(得分:0)

您的示例中似乎不太清楚。

那就是说,

/.*\\(.*)-[^-]*$/

将捕获最后一个反斜杠和最后一个连字符之间的所有文本,无论它匹配什么。