2016-09-21 23 views
2

我最近一直在學習正則表達式。我試圖將FDF對象收集到單個字符串中,然後我可以解析它們。我遇到的問題是我的代碼只匹配第一次出現,並且忽略FDF文件中的所有其他「對象」。c#正則表達式不匹配多次

對象以2個數字和字符串「obj」自行開始,然後回車(不是換行符)。它們在回車和字符串「endobj」後結束。

//testing parsing into objects... 
List<String> FDFobjects = new List<String>(); 

String strRegex = @"^(?<obj>\d+ \d+) obj\r(?<objData>.+?)\rendobj(?=\r)"; 
Regex useRegex = new Regex(strRegex, RegexOptions.Multiline | RegexOptions.Singleline); 

StreamReader reader = new StreamReader(FileName); 
String fdfString = reader.ReadToEnd(); 
reader.Close(); 

foreach (Match useMatch in useRegex.Matches(fdfString)) 
    FDFobjects.Add(useMatch.Groups["objData"].Value); 

if (FDFobjects.Count > 0) 
    Console.WriteLine(FDFobjects[0]); 

Console.WriteLine(FDFobjects.Count); 

(I用$在正則表達式串的結尾,但匹配0次,而使用(= \ R)匹配一次?)

編輯:有些線返回爲CR/LF,有些只是CR。我不知道文件的不同部分是否始終一致,因此我只是檢查它們。我已經解決了以下問題,至今似乎完美地工作(並且我沒有使用Multiline選項)。在你的模式添加背後的外觀是什麼在這裏所作的最大的區別....

... = new Regex(@"(?<=^|[^\\](\r\n|\r|\n))(?<objName>\d+ \d+) obj(\r\n|\r|\n)(?<objData>.*?)(?<!\\)(\r\n|\r|\n)endobj(?=\r\n|\r|\n|$)", RegexOptions.Singleline); 
+0

嘗試'@「^(? \ d + \ d +)obj \ r?\ n(?。+?)\ r?\ nendobj(?= \ r?\ n)」'。也許可以將'\ r'改爲更靈活的'\ r?\ n'。如果沒有確切的樣本字符串,用這種模式來幫助你並不容易。 –

+0

@Wiktor:謝謝。它不起作用。 FDF僅使用回車符,它顯示。 – someprogrammer

+1

然後提供確切的輸入字符串和準確的期望輸出。 –

回答

0

^只會匹配字符串的開始。改爲嘗試\b

+2

第一個對象不在字符串的開頭,它匹配。 RegexOptions.Multiline選項應該改變^和$的匹配。 – someprogrammer

+0

好點...我從來沒有嘗試過混合過'Singleline'和'Multiline' - 你真的需要兩個嗎? – dahlbyk

+1

我聽到你的聲音。不幸命名爲「單線」和「多線」選項無關。 「單行」與點是否匹配新行有關。 – someprogrammer

0

似乎MSDN Regex Web help說謊關於什麼^比賽:

^   -     匹配的搜索字符串的開始位置。如果標誌中包含m(多行搜索)字符,則^也與\n\r後面的位置匹配。

它只\n後的位置匹配時,看到following demo@"(?m)^\d+"圖案在"1\r\n2\r3\n4"輸入匹配1243前面帶有\r)。

使用(?<=\r|^)在開始和(?=\r|$)末:

var s = "1 2 obj\rObj1\rendobj\r2 3 obj\rObj2\rendobj\r3 45 obj\rObj3\rendobj"; 
var matches = Regex.Matches(s, @"(?<=\r|^)(?<obj>\d+ \d+) obj\r(?<objData>.+?)\rendobj(?=\r|$)", 
     RegexOptions.Multiline | RegexOptions.Singleline); 
foreach (Match m in matches) 
{ 
    Console.WriteLine("___ MATCH ___"); 
    Console.WriteLine(m.Value); 
} 

輸出所有三場比賽:

___ MATCH ___ 
1 2 obj 
Obj1 
endobj 
___ MATCH ___ 
2 3 obj 
Obj2 
endobj 
___ MATCH ___ 
3 45 obj 
Obj3 
endobj 

C# demo online

+0

感謝您的輸入。這似乎是多行選項沒有做它應該做的,但我不記得細節。 (從那以後我就睡了。) – someprogrammer

+0

這個選項相當棘手。我以爲我知道它很好,但你的問題是大開眼界:) –