2016-07-11 3 views
2

区切り文字の間のものを除くすべての改行文字:試合、私は以下のCSVファイル与えた

"A";"B 
C";"D" 
"E";"F" 
"G 
H" 

をそして私は2つの間に直接配置するものを除いて、テキストに配置されている改行文字を取り除く必要がありますデリミタ(その場合は二重引用符"")。 2つの二重引用符("\n")の間の唯一の記号である改行文字のみがファイルに存在する必要があります。

アイデアはその意志、正規表現を持つことです。それぞれの行は、常に起動するよう

は、行の最後にあるものを除き、二重引用符(間のものを除いて、すべての新しい行の文字を検索し、二重引用符で終わる)をスペースで置き換えます。

だから、上記のファイルを処理した結果は次のようになります。

つまりそう
"A";"B C";"D" 
"E";"F" 
"G H" 

、正規表現の区切り文字の間に改行文字を検索する必要があります。

"\n"

を除くすべての \nを検索

次の正規表現を試しました:[^"\n"][\n]\nと一致するように"\n"、しかし、崇高なテキスト2でこれをテストすることは望んでいた改行文字でなく、単一の文字、その前にを選択:私はスペースを持つもの見つかった場所を交換するとき、それはまた置き換えることを意味します

enter image description here

BおよびG文字ですが、これは予期しないものです。

また、私はその正規表現を使用してC#コードで置換演算を実行することをお伝えしたいと思います。

私が望むようにこれを動作させる方法はありますか?

EDIT 2016年7月14日

私はOmegaMan何を試してみました以下の提案。 上記のケースではうまく動作しますが、ファイル内の複数行にまたがっている可能性があります。例:

考えるとCSVファイル(後にC#コードで "pathToTheExampleFile" と呼ばれる):

"A";"B C";"D" 
"E";"F";"Part1 Part2 
Part3 
"; 

"A";"B 
C";"D" 
"E";"F";"Part1 
Part2 
Part3 
"; 

コードでOmegaManのソリューションを使用して、私はこの結果を得ます

これは、次のようになります。

"A";"B C";"D" 
"E";"F";"Part1 Part2 Part3 "; 

これまで、単にそのようなOmegaManの操作を交換3回、実行した後:

string data = File.ReadAllText(@"pathToTheExampleFile"); 

string pattern = @"(?<=\x22[^\x22\r\n]+)([\r\n]+)"; 

var result = Regex.Replace(data, pattern, " "); 

result = Regex.Replace(result, pattern, " "); 

result = Regex.Replace(result, pattern, " "); 

Console.WriteLine(result); 

を私は希望通りの結果を得ます。だから、必要なものにマッチする複数行です。 正規表現が機能しないケースはありません。

正規表現を変更する方法が分かっていれば、感謝します。

EDIT 2016年7月15日:

私はそれがこの醜いソリューションの追加機能することを追加する必要があります。最後に

while (Regex.IsMatch(data, pattern)) 
{ 
    data = Regex.Replace(data, pattern, " "); 
} 

を、dataは、予想される文字列が含まれています。それは非常に醜いですが、私はそれが正規表現と何とかやることができると確信しています。

\n(?!") 

をしててそれを置き換えます:あなたが検索する先読みベースの正規表現を使用することができます

+0

するTry見る(http://regexstorm.net/tester?p=(%3F% 3C%3d%22%5b%5e%22%5d *)%5cr%3f%5cn(%3f!%22)&i =%22A%22%3b%22B%0d%0aC%22%3b%22D%22 %0d%0a%22E%22%3b%22F%22%0d%0a%22G%0d%0aH%22&r = +)。 –

答えて

1

" " 

\n(?!")は、二重引用符が続いていない任意の\nにマッチします。

RegEx Demo

0

私は複雑な正規表現の代わりにループする実装が容易勧め:

private static String trimNewLines(String value) { 
    if (null == value) 
    return value; 

    StringBuilder sb = new StringBuilder(value.Length); 

    Boolean inQuotation = false; 

    foreach (char ch in value) { 
    if (ch == '"') 
     inQuotation = !inQuotation; 

    if (inQuotation || ch != '\r' || ch != '\n') 
     sb.Append(ch); 
    } 

    return sb.ToString(); 
} 

... 

String result = trimNewLines(File.ReadAllText(@"c:\MyData.csv")); 
+0

ルーピングが正規表現マッチングより速いと思いますか?私は500k〜100万行のファイルを扱います。 – DawidSibinski

+0

@DawidSibinski:通常、ループは高速です* –

1

オープン引用されたテキストがあることを確認するために、背後に非がかかる外観を使用することにより、これが仕事をします\x22であることを

string data = "\"A\";\"B\r\nC\";\"D\"\r\n\"E\";\"F\"\r\n\"G\r\nH\""; 

string pattern = @"(?<=\x22[^\x22\r\n]+)([\r\n]+)"; 

Regex.Replace(data, pattern, " ") 

注:と、次のスペースで\r\nを置き換えます"のエスケープ

置き換え戻り、この:

"A";"B C";"D" 
"E";"F" 
"G H" 
+0

ありがとうございます。それはほとんど働いている。ファイルを検討してください:http://pastebin.com/i2pa5Lq9 Replaceの結果は、http://pastebin.com/YkWTT1sVですが、私は期待しています。http://pastebin.com/QjsEiy9r あなたが3回与えたパターンで置き換えを実行すると、期待される結果が得られます。だからこそ、そのような事例を何とかマッチさせるだけのことです... – DawidSibinski

+0

@DawidSibinski質問を更新して、1回目と2回目の失敗の例を追加してください。それを見ると、**複数の**行を交差する状況があるように見えます。それはまったく新しい正規表現パターンである必要があります。このパターンは**最初に**提供したルールにのみ適用されます。他の失敗点はありますか? – OmegaMan

+0

投稿を変更しました。 – DawidSibinski

0

私は、この入力FOT

"A";"B C";"D" 
"E";"F";"Part1 Part2 Part3 " 
"G G2 G3";"H";" I I2 I3 " 

を得た

string pattern = @"([^\x22])(\r\n)+|(;\x22)\r\n"; 
string result = Regex.Replace(data, pattern, "$1$3 "); 

試してみてください。

"A";"B 
C";"D" 
"E";"F";"Part1 
Part2 
Part3 
" 
"G 
G2 
G3";"H";" 
I 

I2 

I3 
" 

[ `(?<= "[^"] *)\ rの?\ n個(?!") `] https://dotnetfiddle.net/uc538C

関連する問題