用于记录更新的复杂字符串解析

时间:2013-03-25 13:01:27

标签: c# regex

考虑以下输入字符串。

var inputString = "Config: EbizNewTestProject.dll PaymentSOAUrl for Paid: http://111.11.11.111/Payment.asp?" + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;
            inputString += "Config: EbizNewTestProject.dll PaymentSOAUrl for Paid: http://111.11.11.111/Payment.asp? " + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;
            inputString += "Config: PartnerServicesTestBase.dll PaymentSOAUrl for Paid: https://172.31.26.38/Payment.asp? " + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>5000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;
            inputString += "Config: PartnerServicesTestBase.dll PaymentSOAUrl for Paid: https://172.31.26.38/Payment.asp? " + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>5000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>" + Environment.NewLine;
            inputString += "Config: EbizNewTestProject.dll PaymentSOAUrl for Paid: http://111.11.11.111/Payment.asp? " + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;

让我们观察一下“异常”的字符串内容(在给出的例子中共有5个)。

FirstOne

Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: 

SecondOne

Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>:

ThirdOne

Exception: <Response> <ReturnCode>5000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>:

FourthOne

Exception: <Response> <ReturnCode>5000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>:

FifthOne

Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>:

如果仔细观察,第一和第二种情况是相同的。第3和第4也是如此。第五名与第一名/第二名相同。

我需要做的是,如果第一个和第二个或连续的“例外”文本是理想的,那么留下第一个,其他将被替换为“Exception:--DO--”。 如果找到了一个但不是连续的符号字符串,那么它将显示为原样。

从此以后,输出将是(原始字符串的所有内容将保持相同,只有匹配的异常将更新,如下所示)

FirstOne

Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>:

SecondOne(因为它与Firstone相同且是连续的)

Exception: --DO--

ThirdOne(因为它是新的)

Exception: <Response> <ReturnCode>5000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>:

FourthOne(因为它与Thirdone相同并且是连续的)

Exception: --DO--

FifthOne(尽管它与第一个/第二个相同,但不是连续序列)

Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>:

我做了这个程序。首先,我根据索引(开始和结束)获取异常的内容,然后将值存储在集合中。然后使用循环我检查第一个和第二个的内容,并进行所需的更新。

但我相信有比这更好的解决方案(可能是正则表达式,linq,lambda组合。)

需要帮助以有效的方式解决这个问题。

由于

3 个答案:

答案 0 :(得分:0)

在谈到Regex时,我仍然是一个主要的新手,但似乎你可以用它们来做...

我还在努力做到这一点,并希望如果我不能足够快地到达那里,大师可以指出你正确的方向,但这是我到目前为止所做的:

匹配的正则表达式:

((Exception.*?)(?=Exception)){2}

基本上,查找以“Exception”开头的字符串并匹配所有内容,直到下次看到“Exception”一词(但第二次不匹配),然后查找相同字符串的2个副本

要更换的正则表达式:

$1Exception: --DO--

意思是,第一次出现并第二次用“Exception:--DO - ”替换

希望这至少让你走上正确的道路,我也会继续玩它。 (再次,对不起,Regex对我来说还是比较新的,我只知道这将是一个很酷的解决方案)

答案 1 :(得分:-1)

我会讨论XML反序列化,它会为你解决很多痛苦:

进口:

using System.Xml.Serialization;
using System.Text.RegularExpressions;

代码:

//find the Reponses with regex
MatchCollection  matches = Regex.Matches(inputString, "<Response>(.)+</Response>");

XmlSerializer serializer = new XmlSerializer(typeof(Response));

List<Response> entityList = new List<Response>();


//Deserialize the reponses
foreach (Match item in matches)
{
    using(System.IO.TextReader rdr = new StringReader(item.Value))
    {
        Response entity = (Response)serializer.Deserialize(rdr);
        entity.Line = item.Value;
        entityList.Add(entity);
    }
}

//now you have real objects which you can treat however you want. Example just a loop or linq or whatever
for (int i = 0; i < entityList.Count; i++)
{
    if (i > 0 && entityList[i - 1].ReturnCode == entityList[i].ReturnCode)
        Console.Out.WriteLine("--DO--");
    else
        Console.Out.WriteLine(entityList[i].Line);
}

和实体:

public class Response
{
    [XmlElement("ReturnCode")]
    public int ReturnCode { get; set; }

    [XmlIgnore()]
    public string Line { get; set; }
}

答案 2 :(得分:-1)

这是我的最终版本

var inputString = "Config: EbizNewTestProject.dll PaymentSOAUrl for Paid: http://111.11.11.111/Payment.asp?" + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;
            inputString += "Config: EbizNewTestProject.dll PaymentSOAUrl for Paid: http://111.11.11.111/Payment.asp? " + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;
            inputString += "Config: PartnerServicesTestBase.dll PaymentSOAUrl for Paid: https://172.31.26.38/Payment.asp? " + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>5000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;
            inputString += "Config: PartnerServicesTestBase.dll PaymentSOAUrl for Paid: https://172.31.26.38/Payment.asp? " + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>5000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;
            inputString += "Config: EbizNewTestProject.dll PaymentSOAUrl for Paid: http://111.11.11.111/Payment.asp? " + Environment.NewLine;
            inputString += "Exception: <Response> <ReturnCode>4000</ReturnCode> <SuccessCode>NO</SuccessCode> <ReturnDesc>System Error</ReturnDesc> <ReturnURL>http://localhost/Default.aspx</ReturnURL> <CustomParameter /> </Response>: " + Environment.NewLine;


            TextReader reader = new StringReader(inputString);
            string line = null;
            StringBuilder sb = new StringBuilder();
            string firstLine = null;


            //append the first line
            sb.AppendLine(reader.ReadLine());

            //read the first exception line
            firstLine = reader.ReadLine();
            sb.AppendLine(firstLine);



            while ((line = reader.ReadLine()) != null)
            {
                if (line.StartsWith("Exception:"))
                {

                    if (line == firstLine)
                    {
                        sb.AppendLine("Exception:-- Do --");
                    }

                    if (line != firstLine)
                    {
                        sb.AppendLine(line);
                        firstLine = line;

                    }
                }
                else
                {
                    sb.AppendLine(line);
                }
            }


            Console.WriteLine(sb.ToString());

            Console.ReadKey();