0

次の文字列を分割したい:

String line ="DOB,1234567890,11,07/05/12,\"first,last\",100,\"is,a,good,boy\"";

次のトークンに:

DOB
1234567890
11
07/05/12
first,last
100
is,a,good,boy

次の正規表現を使用してみました:

import java.util.*;
import java.lang.*;
import java.util.regex.*;
import org.apache.commons.lang.StringUtils;

class SplitString{

    public static final String quotes = "\".[[((a-z)|(A-Z))]+( ((a-z)|(A-Z)).,)*.((a-z)|(A-Z))].\"" ;
    public static final String ISSUE_UPLOAD_FILE_PATTERN = "((a-z)|(A-Z))+ [(((a-z)|(A-Z)).,)* + ("+quotes+".,) ].((a-z)|(A-Z)) + ("+quotes+")";

    public static void main(String[] args){

        String line ="DOB,1234567890,11,07/05/12,\"first,last\",100,\"is,a,good,boy\"";
        String delimiter = ",";

    Pattern p = Pattern.compile(ISSUE_UPLOAD_FILE_PATTERN);

    Pattern pattern = Pattern.compile(ISSUE_UPLOAD_FILE_PATTERN);
    String[] output = pattern.split(line);

    System.out.println(" pattern: "+pattern);

    for(String a:output){
        System.out.println(" output: "+a);
    }

    }             
}

正規表現に欠けているものはありますか?

4

2 に答える 2

1

これは、期待される出力を提供するコードの更新バージョンです。

public static final String ISSUE_UPLOAD_FILE_PATTERN = "(?<=(^|,))(([^\",]+)|\"([^\"]*)\")(?=($|,))";
public static void main(String[] args) {
    String line = "DOB,1234567890,11,07/05/12,\"first,last\",100,\"is,a,good,boy\"";
    Matcher matcher = Pattern.compile(ISSUE_UPLOAD_FILE_PATTERN).matcher(line);
    while (matcher.find()) {
        if (matcher.group(3) != null) {
            System.out.println(matcher.group(3));
        } else {
            System.out.println(matcher.group(4));
        }
    }
}

正規表現は次のよう に機能します(?<=(^|,))::一致する前の文字が文字列の始まりである,
(([^\",]+)|\"([^\"]*)\")か::一致するか:一致する"<any number of (not")>"any number of (not" or ,)
(?=($|,))の文字が文字列の終わりであるかを確認するか、,
結果はグループ3または4になります。どの部分が一致しました。

于 2012-07-10T08:45:49.167 に答える
0

あなたの正規表現は and で奇妙なことを[]ます: これらの使用は、文字範囲のようには見えません。このため、わざわざあなたの表現をすべて解読して修正することはしませんでした。

2番目の注意として、正規表現が何を記述すべきかを確認する必要があります.トークン間の区切り文字と一致させますか、それとも個々の非区切り文字トークンと一致させますか? split メソッドの使用は前者を意味しますが、あなたのアプリケーションでは後者の方が実現しやすいと思います。実際、私の最近の回答では、csv ファイルのトークンに一致する正規表現を思いつきました。

String tokenPattern = "\"[^\"]*(\"\"[^\"]*)*\"|[^,]*";

これは一致します

  • 次のカンマまでの引用符で囲まれていない文字列
  • 埋め込まれたコンマを含む、終了引用符までの引用文字列
  • 二重引用符を含む引用符付き文字列

これを使用して、行のマッチャーを作成し、 を使用してすべての一致を反復し、 を使用findしてトークンを抽出できますgroup()。列のセマンティック値が必要な場合は、そのループを使用して引用符を削除し、二重引用符を単一引用符に変換することもできます。

別の方法として、もちろん、質問へのコメントで提案されている CSV リーダーを使用することもできます。

于 2012-07-10T08:42:52.433 に答える