2010-10-22 52 views
2

我有一個文本文件,每天由舊計算機系統自動生成。查找字符串中的字符索引

不幸的是,這個文件中的列沒有分隔,它們也不是完全固定的寬度(每一列的寬度可能會根據每列中數據的字符數量而改變)。該文件確實有列標題,所以我想使用列標題查找每列的寬度。這裏是列標題行的例子:

JOB_NO[variable amount of white space chars]FILE_NAME[variable amount of ws chars]PROJECT_CODE[variable amount of ws chars][carriage return] 

我想要做的就是在列的第一個字符和一列的最後一個空白的索引(從列標題的索引)。我想獲得JOB_NUM中「J」的索引和FILE_NAME中第一列中「F」之前的最後一個空白。

我想我還應該提到,列可能並不總是按照相同的順序,但它們將具有相同的標題名稱。

有關如何做到這一點在VB.net或c#的任何想法?我知道我可以使用string.indexOf(「JOB_NO」)來獲取列開頭的索引,但是如何獲得每列中最後一個空格的索引? (或者在下一個表示下一列開始的第一個非空白之前的最後一個空格)

+0

有沒有acctualy []或僅僅是例如空間的位置。沒有[]沒有[ – rerun 2010-10-22 20:10:09

+0

]。這只是例如空白的地方。 – avword 2010-10-22 20:14:05

回答

2

獲取所有列的索引。例如

var jPos = str.IndexOf("JOB_NO"); 
var filePos = str.IndexOf("FILE_NAME"); 
var projPos = str.IndexOf("PROJECT_CODE"); 

然後在數組中排序它們。從最小到最大。現在你知道你的列順序。第一列的最後一個空格是[the_next_column's_index] -1。

int firstColLastSpace = ar[1] -1; 
int secColLastSpace = ar[2] -1; 
0

大量借用previous answer I've given ...要獲得專欄職位,這個怎麼樣?我假設列名不包含空格。

IEnumerable<int> positions=Regex 
    .Matches("JOB_NUM FILE_NAME   SOME_OTHER_THING",@"(?<=^|)\w") 
    .Cast<Match>() 
    .Select(m=>m.Index); 

(上述的詳細的版本)

//first get a MatchCollection 
//this regular expression matches a word character that immediately follows 
//either the start of the line or a space, i.e. the first char of each of 
//your column headers 
MatchCollection matches=Regex 
    .Matches("JOB_NUM FILE_NAME   SOME_OTHER_THING",@"(?<=^|)\w"); 
//convert to IEnumerable<Match>, so we can use Linq on our matches 
IEnumerable<Match> matchEnumerable=matches.Cast<Match>(); 
//For each match, select its Index 
IEnumerable<int> positions=matchEnumerable.Select(m=>m.Index); 
//convert to array (if you want) 
int[] pos_arr=positions.ToArray(); 
+0

對不起,我無法弄清楚如何使用該表達式的輸出。 「新正則表達式...」是否返回一個值? – avword 2010-10-22 20:47:52

+0

我已經重寫了我的答案,以明確發生了什麼事情。沒有必要實例化一個新的正則表達式來獲得MatchCollection,但是是的......「新正則表達式」返回一個新的正則表達式實例,我在其中調用Matches方法。由於Regex有一個靜態匹配方法,所以最好使用它。表達式的輸出是IEnumerable 。 (我已經在我的編輯中指出了這一點)。如果你對這些類型的集合感到高興,你可以調用ToList或ToArray。 – spender 2010-10-22 21:57:31

0

下面是使用一個小的類,你可以在以後使用解析您的線路的備選答案。您可以使用fields集合作爲模板來爲每個行拖出字段,但此解決方案不會忽略空格,因爲我認爲它們是可變的,因爲每天的字段長度不一,您需要該數據:

Imports System.Text.RegularExpressions 

Module Module1 

    Sub Main() 

     Dim line As String = "JOB_NUM  FILE_NAME   SOME_OTHER_THING " 
     Dim Fields As List(Of Field) = New List(Of Field) 
     Dim oField As Field = Nothing 

     Dim mc As MatchCollection = Regex.Matches(
      line, "(?<=^|)\w") 

     For Each m As Match In mc 
      oField = New Field 
      oField.Start = m.Index 
      'Loop through the matches 
      If m.NextMatch.Index = 0 Then 
       'This is the last field 
       oField.Length = line.Length - oField.Start 
      Else 
       oField.Length = m.NextMatch.Index - oField.Start 
      End If 
      oField.Name = line.Substring(oField.Start, oField.Length) 
      'Trim the field name: 
      oField.Name = Trim(oField.Name) 
      'Add to the list 
      Fields.Add(oField) 
     Next 

     'Check the Fields: you can use line.substring(ofield.start, ofield.length) 
     'to parse each line of your file. 

     For Each f As Field In Fields 
      Console.WriteLine("Field Name: " & f.Name) 
      Console.WriteLine("Start: " & f.Start) 
      Console.WriteLine("Length " & f.Length) 
     Next 

     Console.Read() 
    End Sub 

    Class Field 
     Public Property Name As String 
     Public Property Start As Integer 
     Public Property Length As Integer 
    End Class 

End Module