C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: 「,」によるSplit


(過去ログ 45 を表示中)

[トピック内 11 記事 (1 - 11 表示)]  << 0 >>

■24061 / inTopicNo.1)  「,」によるSplit
  
□投稿者/ meguron (1回)-(2008/08/27(Wed) 12:43:07)

分類:[C#] 

VS2008,FW3.5で
正規表現によるSplitの書き方を教えて下さい


using System;
using System.Text.RegularExpressions;

namespace ConsoleApplication1 {
class Program {
static void Main( string[] args ) {
string sBuf = "\"abc,xyz\",\"123,456\",777,333";
Regex oRegex = new Regex(",(?=(([^\"]*\"){2})*[^\"]*$)");
string[] sLineData = oRegex.Split(sBuf);
foreach ( string sTemp in sLineData ) {
Console.WriteLine(sTemp);
}
}
}
/*
実行結果
"abc,xyz"
"123,456"
123,456"
"123,456"
777
333

期待する結果
"abc,xyz"
"123,456"
777
333
*/
}

引用返信 編集キー/
■24070 / inTopicNo.2)  Re[1]: 「,」によるSplit
□投稿者/ やじゅ (584回)-(2008/08/27(Wed) 13:49:14)
やじゅ さんの Web サイト
No24061 (meguron さん) に返信

コードだけ提示されても、目的かかないと駄目ですよ。

カンマがあっても、二重引用符で囲まれたものはカンマが無いものとして扱いたいわけですよね。

正規表現一発では難しいかな(私の実力がないだけですけどw)

二重引用符で囲まれたものはカンマを別に文字に置換とかした上でやるとかすればいいだろうけど。

素直に文字列読んで判断した方が楽だな


引用返信 編集キー/
■24081 / inTopicNo.3)  Re[2]: 「,」によるSplit
□投稿者/ れい (756回)-(2008/08/27(Wed) 14:55:24)

正規表現は何でも1回で出来るものではないので、
引用符などエスケープの処理は大変な場合もあります。

もし引用符が何処に出現するかわからないなら、
置換しておいてからsplitがよいとおもいます。

引用符の出現回数が必ず1回であるというような回数の保証があるなら
("[^"]*?"|[^",]*)
こんな感じの文字列で何とかなるでしょう。

私ならやじゅさんの言うように頭から読みます。
引用返信 編集キー/
■24088 / inTopicNo.4)  Re[3]: 「,」によるSplit
□投稿者/ meguron (2回)-(2008/08/27(Wed) 15:40:54)
No24081 (れい さん) に返信
> 引用符の出現回数が必ず1回であるというような回数の保証があるなら
> ("[^"]*?"|[^",]*)
> こんな感じの文字列で何とかなるでしょう。

やって見ましたが今一です。
using System;
using System.Text.RegularExpressions;

namespace ConsoleApplication1 {
    class Program {
        static void Main( string[] args ) {
            string sBuf = "\"abc,xyz\",\"123,456\",777,333";
            string sPtm = "(\"[^\"]*?\"|[^\",]*)";
            Regex oRegex = new Regex(sPtm);
            string[] sLineData = oRegex.Split(sBuf);
            for ( int iLoop =0 ; iLoop < sLineData.Length ; iLoop++ ) {
                Console.WriteLine("{0} : {1}" , iLoop , sLineData[iLoop]);
            }
        }
    }
    /*
     実行結果
    0 :
    1 : "abc,xyz"
    2 :
    3 :
    4 : ,
    5 : "123,456"
    6 :
    7 :
    8 : ,
    9 : 777
    10 :
    11 :
    12 : ,
    13 : 333
    14 :
    15 :
    16 :

     * 期待する結果
    0 : "abc,xyz"
    1 : "123,456"
    2 : 777
    3 : 333
     */
}



引用返信 編集キー/
■24092 / inTopicNo.5)  Re[4]: 「,」によるSplit
□投稿者/ Ognac (10回)-(2008/08/27(Wed) 17:07:55)
SingleかDoubleQuatationを考慮した分離の例です。
目的の語句が Group <fact> に入ります。
Single/Double Quateがない素の文字列の時は <q1>が未確定なので、(q1)\kは無視されるので、分離可能です。

"\s*(?<q1>[""']?)(?<fact>.*?)(?(q1)\k<q1>)\s*(?=(,|$))"

引用返信 編集キー/
■24094 / inTopicNo.6)  Re[5]: 「,」によるSplit
□投稿者/ meguron (3回)-(2008/08/27(Wed) 17:40:02)
No24092 (Ognac さん) に返信
正規表現に詳しくないのですが、

> Single/Double Quateがない素の文字列の時は <q1>が未確定なので、(q1)\kは無視されるので、分離可能です。
> "\s*(?<q1>[""']?)(?<fact>.*?)(?(q1)\k<q1>)\s*(?=(,|$))"

"\s*("(?:[^"]|"")*"|[^,]*)\s*,"の方がまだ良い結果を出してくれます。

using System;
using System.Text.RegularExpressions;

namespace ConsoleApplication1 {
    class Program {
        static void Main( string[] args ) {
            string sBuf = "\"abc,xyz\",\"123,456\",777,333";
            string sPtm = string.Empty;
            sPtm = "\\s*(\"(?:[^\"]|\"\")*\"|[^,]*)\\s*,";
//            sPtm = "\\s*(?<q1>[\"\"']?)(?<fact>.*?)(?(q1)\\k<q1>)\\s*(?=(,|$))";
            Regex oRegex = new Regex(sPtm);
            string[] sLineData = oRegex.Split(sBuf);
            for ( int iLoop =0 ; iLoop < sLineData.Length ; iLoop++ ) {
                Console.WriteLine("{0} : {1}" , iLoop , sLineData[iLoop]);
            }
        }
    }

    /*
     実行結果
    0 :
    1 : "abc,xyz"
    2 :
    3 : "123,456"
    4 :
    5 : 777
    6 : 333

     * 期待する結果
    0 : "abc,xyz"
    1 : "123,456"
    2 : 777
    3 : 333
     */
}

引用返信 編集キー/
■24095 / inTopicNo.7)  Re[6]: 「,」によるSplit
□投稿者/ れい (758回)-(2008/08/27(Wed) 17:46:07)
No24094 (meguron さん) に返信
> ■No24092 (Ognac さん) に返信
> 正規表現に詳しくないのですが、
>
>>Single/Double Quateがない素の文字列の時は <q1>が未確定なので、(q1)\kは無視されるので、分離可能です。
>>"\s*(?<q1>[""']?)(?<fact>.*?)(?(q1)\k<q1>)\s*(?=(,|$))"
>
> "\s*("(?:[^"]|"")*"|[^,]*)\s*,"の方がまだ良い結果を出してくれます。

meguronさんの望んだものを望んだ形で回答してくれるとは限りません。
Regexについて、背景知識が少し足りないようにも見えます。

MSDNのRegex.SplitやRegex.Matchなどをよく読んでみるといいと思いますよ。
引用返信 編集キー/
■24136 / inTopicNo.8)  Re[7]: 「,」によるSplit
□投稿者/ THREE-ONE (14回)-(2008/08/28(Thu) 10:48:39)
THREE-ONE さんの Web サイト
string text = "\"abc,xyz\",\"123,456\",777,333";
string pattern = "(\"[^\"]+\"(?=,))|((?!\")[^,]+(?!\"))";
Regex regex = new Regex(pattern);
MatchCollection matches = regex.Matches(text);
for (int i = 0; i < matches.Count; i++)
{
    Console.WriteLine("{0} : {1}", i, matches[i].Value);
}

提示されている例だけならば、これでいけるでしょう。
Split にこだわりたいなら別ですが。
ですが、よくあるExcelのように、要素内の " が "" でエスケープされるような CSV の場合はこれでは不可能です。
CSV の形式にまだいくつかの条件があるならば、私も頭から一文字ずつ読み込んで処理することをお勧めします。
正規表現に頼っていると、予想外のパターンのときにデバッグや修正が面倒になったりしますので。

引用返信 編集キー/
■24155 / inTopicNo.9)  Re[8]: 「,」によるSplit
□投稿者/ meguron (4回)-(2008/08/28(Thu) 13:38:31)
No24136 (THREE-ONE さん) に返信
> 提示されている例だけならば、これでいけるでしょう。
ありがとう

CSVの分解ルーチンて
みなさん、ごりごりコーディングしているのでしょうか

デザパタでのサンプルが乗っているサイトを知っていましたら
教えて下さい。



解決済み
引用返信 編集キー/
■24168 / inTopicNo.10)  Re[9]: 「,」によるSplit
□投稿者/ (報告) (5回)-(2008/08/28(Thu) 16:59:39)
マルチポストリンク
http://okwave.jp/qa4284614.html
引用返信 編集キー/
■24171 / inTopicNo.11)  Re[10]: 「,」によるSplit
□投稿者/ ロック (70回)-(2008/08/28(Thu) 17:15:48)
あがってきたんで、ついでに載せておきます。
http://www.atmarkit.co.jp/fdotnet/dotnettips/487csvparser/csvparser.html

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -