2016-09-21 21 views
2

私は最近正規表現について学んでいます。私は個々の文字列にFDFオブジェクトを集めようとしています。それを解析することができます。私が抱えている問題は、私のコードが最初のオカレンスと一致するだけで、FDFファイルの他のすべての "オブジェクト"は無視されるということです。#regexが複数回一致しない

オブジェクトは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); 

(、私は正規表現文字列の末尾に$を使用していたが、それは0回にマッチし、一度(= \ r)が一致して使用し、一方、?。)

編集を:いくつかの改行がCR /ありますLF、一部はCRです。私はそれがファイルのさまざまな部分に対して常に一貫しているかどうかはわかりません。だから、私はそれらのすべてをチェックします。私はこれまで完璧に動作していると思われる以下を解決しました(そして私は複数行オプションを使用していません)。後ろの外観を追加すると、ここでの最大の違いを作ったものです....あなたのパターンで

... = 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

お聞きします。残念なことに「Singleline」と「Multiline」のオプションは無関係です。 "Singleline"は、ドットが新しい行と一致するかどうかに関係します。 – someprogrammer

0

MSDN Regex Web helpは何^試合について嘘をついているようだ:

^  から    は、検索文字列の先頭と一致します。フラグにm(複数行の検索)文字が含まれている場合、^は、\nまたは\rの次の位置にも一致します。

それだけ\n後の位置と一致し、(3\rで先行される)"1\r\n2\r3\n4"入力に124と一致@"(?m)^\d+"パターンでfollowing demo参照。最後に

使用開始時に(?<=\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); 
} 

出力全て3試合:

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

C# demo onlineを参照してください。

+0

入力いただきありがとうございます。マルチラインオプションは、それがすべきことをしていないようですが、詳細を覚えていません。 (私は当時から眠っていた。) – someprogrammer

+0

そのオプションはややこしい。私はそれをよく知っていたと思ったが、あなたの質問は目を開けていた:) –

関連する問題