2013-02-15 23 views
0

我有一大堆下面這樣格式的文件:字符串解析C#數組/ SQL數據庫

20130201:14:58:47 I search: xx ('ID'= (xxxxxxxx)) 
20130201:14:58:56 I request: search | For ID | Search 
20130201:14:58:56 I search: xx ('ID'= (xxxxxxx)) 

有東西在C#像在Python稱爲restkey?我想抓住前三項(日期時間,我(稱爲操作),搜索/請求),並將每個項插入到SQL表中的自己的列中,然後在第4列中放置該行的其餘部分。

在python中這很容易,但我不能處理所有的箍,我不得不跳過它來插入到我的sql表中。所以我轉移到了C#,與SSMS的連接更容易。

+0

只是說明一下,並不是所有的線都看起來像這三個。 「I」是不同的字母,「搜索」和「請求」是不同的。 – 2013-02-15 23:06:33

+0

是文字「我搜索:xx ~~~在每一行嗎?或者它只是爲了演示嗎?」 – XtrmJosh 2013-02-15 23:09:02

回答

2

雖然String.Split()大概是漂亮的和簡單的方式,我更喜歡使用Regex對於這種分析的。在這種情況下,一個模式是這樣的:

(?<DateTime>\d{8}\:\d{2}\:\d{2}\:\d{2})\s(?<Action>\w)\s(?<SearchOrRequest>search|request)\:\s(?<RestOfTheLine>.*)

給你你所需要的一切,很好地歸納爲「日期時間」,「行動」,「SearchOrRequest」和「RestOfLine」比賽組。

var pattern = "(?<DateTime>\d{8}\:\d{2}\:\d{2}\:\d{2})\s(?<Action>\w)\s(?<SearchOrRequest>search|request)\:\s(?<RestOfTheLine>.*)"; 
var regex = new Regex(pattern); 
var match = regex.Match(inputString); 

var theDate = match.Groups["DateTime"].Value; 
var theAction = match.Groups["Action"].Value; 
var theChoice = match.Groups["SearchOrRequest"].Value; 
var theRest = match.Groups["RestOfTheLine"].Value; 
+0

我喜歡你的正則表達式。 – 2013-02-15 23:41:13

+0

他在一個評論中提出,除了「搜索」或「請求」對於第三場比賽,但假設他們都是一個單詞,您可以將該模式更改爲\ w +並執行 – 2013-02-15 23:50:59

+0

@PrestonGuillot沒有禁止*使用StringBuilder構建模式字符串,該答案是一個釣魚竿,而不是魚 – 2013-02-16 00:08:48

0

使用string.Split方法

string myString = "20130201:14:58:47 I search: xx (\'ID\'= (xxxxxxxx))" 

string[] strarr = myString.split(' '); 

string theLetterIVariableThing = strarr[1]; 

string iddate = strarr[0]; 

StringBuilder sb = new StringBuilder(); 

for (int i = 1; i < strarr.Length; i++) 
{ 
    sb.Append(strarr[i]); 
    sb.Append(" "); 
} 

string trailingText = sb.ToString(); 

string id = iddate.split(':')[0]; 

sb.Clear(); 

for (int i = 1; i < 4; i++) 
{ 
    sb.Append(iddate.split(':'))[i]; 
} 

string date = sb.ToString(); 

我認爲這會工作,但它可能是圍繞着很長的路要走。

0

您可以使用.NET函數String.Split()來做到這一點。

假設你的日期字符串是固定長度的,這應該工作:

 //string inputStr = "20130201:14:58:47 I search: xx ('ID'= (xxxxxxxx))"; 
     //string inputStr = "20130201:14:58:56 I request: search | For ID | Search"; 
     string inputStr = "20130201:14:58:56 I search: xx ('ID'= (xxxxxxx))"; 

     string dateStr = inputStr.Substring(0, 17); 
     string[] splitStr = inputStr.Substring(18).Split(new char[] { ':' }); 

     string actionStr = splitStr[0].Substring(0, splitStr[0].IndexOf(' ')); 
     string userStr = splitStr[0].Substring(2); 
     string restStr = splitStr[1].TrimStart(); 

     // print out what we parsed 
     Console.WriteLine(inputStr); 
     Console.WriteLine(dateStr); 
     Console.WriteLine(actionStr); 
     Console.WriteLine(userStr); 
     Console.WriteLine(restStr); 

輸出:

20130201:14:58:56 I search: xx ('ID'= (xxxxxxx)) 
20130201:14:58:56 
I 
search 
xx ('ID'= (xxxxxxx)) 
0

我嘗試了略有不同的方法。我創建了一個控制檯程序,可以將這些文件轉換爲完全限定的csv文件。然後你可以很容易地使用ssms導入到sql。

static void Main(string[] args) 
    { 
     if (args.Length == 2) 
     { 
      using (StreamWriter sw = new StreamWriter(args[1])) 
      { 
       using (StreamReader sr = new StreamReader(args[0])) 
       { 
        String line; 

        while ((line = sr.ReadLine()) != null) 
        { 
         int index = 0; 
         int oldIndex = 0; 
         string dateTime = null; 
         string action = null; 
         string task = null; 
         string details = null; 

         index = line.IndexOf(' ', oldIndex); 
         dateTime = line.Substring(oldIndex, index - oldIndex); 
         oldIndex = index + 1; 

         index = line.IndexOf(' ', oldIndex); 
         action = line.Substring(oldIndex, index - oldIndex); 
         oldIndex = index + 1; 

         index = line.IndexOf(':', oldIndex); 
         task = line.Substring(oldIndex, index - oldIndex); 
         oldIndex = index + 1; 

         details = line.Substring(oldIndex + 1); 

         sw.WriteLine("\"{0}\",\"{1}\",\"{2}\",\"{3}\"", dateTime, action, task, details); 
        } 
       } 

      } 
     } 
     else 
     { 
      Console.WriteLine("Usage: program <input> <output>"); 
     } 
    } 
0

這是一個正則表達式可能是正確的使用情況。

var testVectors = new[] 
{ 
    "20130201:14:58:47 I search: xx ('ID'= (xxxxxxxx))", 
    "20130201:14:58:56 I request: search | For ID | Search", 
    "20130201:14:58:56 I search: xx ('ID'= (xxxxxxx))" 
}; 

var expression = @"^(?<TimeStamp>[0-9]{8}(:[0-9]{2}){3}) (?<Action>[^ ]+) (?<Type>search|request): (?<Rest>.*)$"; 

var regex = new Regex(expression); 

foreach (var testVector in testVectors) 
{ 
    var match = regex.Match(testVector); 

    Console.WriteLine(match.Groups["Timestamp"]); 
    Console.WriteLine(match.Groups["Action"]); 
    Console.WriteLine(match.Groups["Type"]); 
    Console.WriteLine(match.Groups["Rest"]); 
} 

使用的措辭做了一些假設 - 你所謂的行動是不包含任何空格,只有searchrequest是有效值我稱之爲類型的字符序列。但如果任何假設不成立,應該很容易採用這種表達方式。