C# 正在分析日志字符串,不带:Split

C# 正在分析日志字符串,不带:Split,c#,regex,string-parsing,C#,Regex,String Parsing,搜索了一下,但我只找到了用逗号左右进行拆分的情况。这种情况是不同的 为了解释我的问题,我将展示一个小例子: JAN 01 00:00:01 <Admin> Action, May have spaces etc. JAN 01 00:00:01动作,可能有空格等。 (这是一个日志条目) 我想把这个字符串解析成几个变量。第一位显然是日期,没有年份。在之间列出登录名,并在日志条目后面列出 配置应具有如下内容: {month} {day} {hour}:{minute}:{second

搜索了一下,但我只找到了用逗号左右进行拆分的情况。这种情况是不同的

为了解释我的问题,我将展示一个小例子:

JAN 01 00:00:01 <Admin> Action, May have spaces etc.
JAN 01 00:00:01动作,可能有空格等。
(这是一个日志条目)

我想把这个字符串解析成几个变量。第一位显然是日期,没有年份。在之间列出登录名,并在日志条目后面列出

配置应具有如下内容:

{month} {day} {hour}:{minute}:{second} <{login}> {the_rest}
{month}{day}{hour}:{minute}:{second}{the_rest}
这将允许更改,而无需对整个内容进行硬编码(使用拆分等)

我认为在这里使用正则表达式可能有用,但我对它知之甚少,也不知道它在这种情况下是否有用。 速度并不重要,但我真的不知道如何做到这一点

谢谢


~Tgys

您可以使用split still,对空格字符进行拆分

显然,您的问题是,您希望在一定数量的拆分之后保留空格,以便“其余”保持在一起

split的可选int参数允许您提供希望执行的最大拆分量,因此可以提供您正在寻找的解决方法


您可以使用split still,对空格字符进行拆分

显然,您的问题是,您希望在一定数量的拆分之后保留空格,以便“其余”保持在一起

split的可选int参数允许您提供希望执行的最大拆分量,因此可以提供您正在寻找的解决方法

string line=“JAN 01 00:00:01 Action,可能有空格等”;
var m=Regex.Match(行,@“(\w{3}\d{2}\d{2}:\d{2}:\d{2})\([\w]+,([\w]+)”;
var date=DateTime.ParseExact(m.Groups[1].Value,“MMM dd HH:mm:ss”,CultureInfo.InvariantCulture);
var user=m.Groups[2]。值;
var action=m.Groups[3]。值;
var text=m.Groups[4]。值;
string line=“JAN 01 00:00:01 Action,可能有空格等”;
var m=Regex.Match(行,@“(\w{3}\d{2}\d{2}:\d{2}:\d{2})\([\w]+,([\w]+)”;
var date=DateTime.ParseExact(m.Groups[1].Value,“MMM dd HH:mm:ss”,CultureInfo.InvariantCulture);
var user=m.Groups[2]。值;
var action=m.Groups[3]。值;
var text=m.Groups[4]。值;

您也可以将其用作正则表达式并使用捕获的组:

^(?<Month>\w{3})\s(?<Day>\d{2})\s(?<Hour>\d{2}):(?<Min>\d{2}):(?<Sec>\d{2})\s(?<User>\<(\w.+?)\>)(.+)$
^(?\w{3})\s(?\d{2})\s(?\d{2}):(?\d{2}):(?\d{2})\s(?\)(.+)$


编辑:缺少用户部分。

您也可以将其用作正则表达式并使用捕获的组:

^(?<Month>\w{3})\s(?<Day>\d{2})\s(?<Hour>\d{2}):(?<Min>\d{2}):(?<Sec>\d{2})\s(?<User>\<(\w.+?)\>)(.+)$
^(?\w{3})\s(?\d{2})\s(?\d{2}):(?\d{2}):(?\d{2})\s(?\)(.+)$


编辑:缺少用户部分。

您可以使用此正则表达式:

(?<Month>[A-Z]{3})\s(?<Day>[0-9]{1,2})\s(?<Hour>[0-9]{1,2}):(?<Minute>[0-9]{1,2}):(?<Second>[0-9]{1,2})\s<(?<Login>[^>]+)>(?<Rest>.*)
(?[A-Z]{3})\s(?[0-9]{1,2})\s(?[0-9]{1,2}):(?[0-9]{1,2}):(?[0-9]{1,2})\s]+)>(?*)
这是一个有点笨拙和复杂,但我希望下面的例子将得到你想要的

class Foo
{
public string Month { get; set; }
public int Day { get; set; }
public int Hour { get; set; }
public int Minute { get; set; }
public int Second { get; set; }
public string Login { get; set; }
public string Rest { get; set; }
}

string strRegex = @"(?<Month>[A-Z]{3})\s(?<Day>[0-9]{1,2})\s(?<Hour>[0-9]{1,2}):(?<Minute>[0-9]{1,2}):(?<Second>[0-9]{1,2})\s<(?<Login>[^>]+)>(?<Rest>.*)";
RegexOptions myRegexOptions = RegexOptions.None;
Regex myRegex = new Regex(strRegex, myRegexOptions);
string strTargetString = @"JAN 01 00:00:01 <Admin> Action, May have spaces etc. \n";

foreach (Match myMatch in myRegex.Matches(strTargetString))
{
    if (myMatch.Success)
    {
        new Foo
        {
            Month = myMatch.Groups["Month"].Value,
            Day = Convert.ToInt32(myMatch.Groups["Day"].Value),
            Hour = Convert.ToInt32(myMatch.Groups["Hour"].Value),
            Minute = Convert.ToInt32(myMatch.Groups["Minute"].Value),
            Second = Convert.ToInt32(myMatch.Groups["Second"].Value),
            Login = myMatch.Groups["Login"].Value,
            Rest = myMatch.Groups["Rest"].Value
        }
    }
}
class-Foo
{
公共字符串月份{get;set;}
公共整数日{get;set;}
公共整数小时{get;set;}
公共整数分钟{get;set;}
公共整数秒{get;set;}
公共字符串登录{get;set;}
公共字符串Rest{get;set;}
}
字符串strRegex=@“(?[A-Z]{3})\s(?[0-9]{1,2})\s(?[0-9]{1,2}):(?[0-9]{1,2}):(?[0-9]{1,2})\s]+)>(?*”;
RegexOptions myRegexOptions=RegexOptions.None;
正则表达式myRegex=新正则表达式(strRegex,myRegexOptions);
字符串strTargetString=@“JAN 01 00:00:01操作,可能有空格等。\n”;
foreach(在myRegex.Matches中匹配myMatch(strTargetString))
{
如果(myMatch.Success)
{
新富
{
月=myMatch.Groups[“月”]。值,
Day=转换.ToInt32(myMatch.Groups[“Day”].Value),
小时=转换.ToInt32(myMatch.Groups[“小时”].Value),
分钟=转换.ToInt32(myMatch.Groups[“分钟”].Value),
Second=Convert.ToInt32(myMatch.Groups[“Second”].Value),
Login=myMatch.Groups[“Login”].Value,
Rest=myMatch.Groups[“Rest”].Value
}
}
}

您可以使用此正则表达式:

(?<Month>[A-Z]{3})\s(?<Day>[0-9]{1,2})\s(?<Hour>[0-9]{1,2}):(?<Minute>[0-9]{1,2}):(?<Second>[0-9]{1,2})\s<(?<Login>[^>]+)>(?<Rest>.*)
(?[A-Z]{3})\s(?[0-9]{1,2})\s(?[0-9]{1,2}):(?[0-9]{1,2}):(?[0-9]{1,2})\s]+)>(?*)
这是一个有点笨拙和复杂,但我希望下面的例子将得到你想要的

class Foo
{
public string Month { get; set; }
public int Day { get; set; }
public int Hour { get; set; }
public int Minute { get; set; }
public int Second { get; set; }
public string Login { get; set; }
public string Rest { get; set; }
}

string strRegex = @"(?<Month>[A-Z]{3})\s(?<Day>[0-9]{1,2})\s(?<Hour>[0-9]{1,2}):(?<Minute>[0-9]{1,2}):(?<Second>[0-9]{1,2})\s<(?<Login>[^>]+)>(?<Rest>.*)";
RegexOptions myRegexOptions = RegexOptions.None;
Regex myRegex = new Regex(strRegex, myRegexOptions);
string strTargetString = @"JAN 01 00:00:01 <Admin> Action, May have spaces etc. \n";

foreach (Match myMatch in myRegex.Matches(strTargetString))
{
    if (myMatch.Success)
    {
        new Foo
        {
            Month = myMatch.Groups["Month"].Value,
            Day = Convert.ToInt32(myMatch.Groups["Day"].Value),
            Hour = Convert.ToInt32(myMatch.Groups["Hour"].Value),
            Minute = Convert.ToInt32(myMatch.Groups["Minute"].Value),
            Second = Convert.ToInt32(myMatch.Groups["Second"].Value),
            Login = myMatch.Groups["Login"].Value,
            Rest = myMatch.Groups["Rest"].Value
        }
    }
}
class-Foo
{
公共字符串月份{get;set;}
公共整数日{get;set;}
公共整数小时{get;set;}
公共整数分钟{get;set;}
公共整数秒{get;set;}
公共字符串登录{get;set;}
公共字符串Rest{get;set;}
}
字符串strRegex=@“(?[A-Z]{3})\s(?[0-9]{1,2})\s(?[0-9]{1,2}):(?[0-9]{1,2}):(?[0-9]{1,2})\s]+)>(?*”;
RegexOptions myRegexOptions=RegexOptions.None;
正则表达式myRegex=新正则表达式(strRegex,myRegexOptions);
字符串strTargetString=@“JAN 01 00:00:01操作,可能有空格等。\n”;
foreach(在myRegex.Matches中匹配myMatch(strTargetString))
{
如果(myMatch.Success)
{
新富
{
月=myMatch.Groups[“月”]。值,
Day=转换.ToInt32(myMatch.Groups[“Day”].Value),
小时=转换.ToInt32(myMatch.Groups[“小时”].Value),
分钟=转换.ToInt32(myMatch.Groups[“分钟”].Value),
Second=Convert.ToInt32(myMatch.Groups[“Second”].Value),
Login=myMatch.Groups[“Login”].Value,
Rest=myMatch.Groups[“Rest”].Value
}
}
}

下面的正则表达式将实现此功能

^([A-Z]{3})\s*([0-9]{1,2})\s*([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})\s*<(.+)>\s*(.+)
^([A-Z]{3})\s*([0-9]{1,2})\s*([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})\s*\s*(.+)
使用一个在线测试工具对其进行了测试

它将返回7个捕获的组

  • 第1组:([A-Z]{3}):月
  • 第2组:([0-9]{1,2}):天
  • 第3组:([0-9]{1,2}):小时
  • 第4组:([0-9]{1,2}):分钟
  • 第5组:([0-9]{1,2}):第二组
  • 第6组:(.+):用户名
  • 第7组:(.+):其余

    • 下面的正则表达式将实现这一功能

      ^([A-Z]{3})\s*([0-9]{1,2})\s*([0-9]{1,2}):([0-9]{1,2}):([0-9]{1,2})\s*<(.+)>\s*(.+)
      
      ^([A-Z]{3})\s*([0-9]{1,2})\s*([0-9]{1,2}):([0
      
      "{month} {day} {hour}:{the_rest}"
      
      var format = "{month} {day} {hour}:{the_rest}";
      var result = Regex.Replace(format, @"\{(\w+)\}", m => groups[m.Groups[1].Value]);
      
      var format = "{month} {day} {hour}:{the_rest}";
      var re = Regex.Replace(format,
                             @"\{(\w+)\}",
                             m => string.Format("(?<{0}>{1})", m.Groups[1].Value, groups[m.Groups[1].Value]));
      var regex = new Regex("^" + re + "$", RegexOptions.ExplicitCapture);
      var match = regex.Match(str);
      
      var results = regex.GetGroupNames().ToDictionary(n => n, n => match.Groups[n].Value);
      
      var input = "JAN 01 00:00:01 <Admin> Action, May have spaces etc.";
      var format = "{month} {day} {hour}:{the_rest}";
      var results = Parse(input, format);