1

次のようなCSV(カンマ区切り)ファイルから行を解析したい:

Bosh,Mark,mark@gmail.com,"3, Institute","83, 1, 2",1,21

ファイルを解析する必要があり、アポストロフィ間のコンマの代わりに、次のように「;」を使用します。

Bosh,Mark,mark@gmail.com,"3; Institute","83; 1; 2",1,21

次のJavaコードを使用していますが、うまく解析できません:

Pattern regex = Pattern.compile("(\"[^\\]]*\")");
        Matcher matcher = regex.matcher(line);
        if (matcher.find()) {
            String replacedMatch = matcher.group();
            String gr1 = matcher.group(1);
            gr1.trim();
            replacedMatch = replacedMatch.replace(",", ";");
            line = line.replace(matcher.group(), replacedMatch);
        }

出力は次のとおりです。

Bosh,Mark,mark@gmail.com,"3; Institute";"83; 1; 2",1,21

誰もこれを修正する方法を知っていますか?

4

6 に答える 6

3

,これは、引用符内を に置き換える私の解決策;です。引用符で囲まれた文字列に表示される場合は、別の によってエスケープされると想定しています。このプロパティは、開始から現在の文字までカウントすることを保証します。引用符の数が奇数の場合、その文字は引用符で囲まれた文字列内にあります。"""

// Test string, with the tricky case """", which resolves to
// a length 1 string of single quote "
String line = "Bosh,\"\"\"\",mark@gmail.com,\"3, Institute\",\"83, 1, 2\",1,21";

Pattern pattern = Pattern.compile("\"[^\"]*\"");
Matcher matcher = pattern.matcher(line);

int start = 0;

StringBuilder output = new StringBuilder();

while (matcher.find()) {
  // System.out.println(m.group() + "\n " + m.start() + " " + m.end());
  output
    .append(line.substring(start, matcher.start())) // Append unrelated contents
    .append(matcher.group().replaceAll(",", ";")); // Append replaced string

  start = matcher.end();
}
output.append(line.substring(start)); // Append the rest of unrelated contents

// System.out.println(output);

で行ったように、一致したグループを置き換える方法に失敗するケースは見つかりませんがline = line.replace(matcher.group(), replacedMatch);、文字列を最初から再構築する方が安全だと思います.

于 2012-06-29T10:23:45.380 に答える
2

方法は次のとおりです。

import java.util.regex.*;

class Main {

  public static void main(String[] args) {

    String in = "Bosh,Mark,mark@gmail.com,\"3, \"\" Institute\",\"83, 1, 2\",1,21";
    String regex = "[^,\"\r\n]+|\"(\"\"|[^\"])*\"";
    Matcher matcher = Pattern.compile(regex).matcher(in);
    StringBuilder out = new StringBuilder();

    while(matcher.find()) {
      out.append(matcher.group().replace(',', ';')).append(',');
    }

    out.deleteCharAt(out.length() - 1);
    System.out.println(in + "\n" + out);
  }
}

印刷されます:

Bosh,Mark,mark@gmail.com,"3, "" 研究所","83, 1, 2",1,21
Bosh,Mark,mark@gmail.com,"3; "" 研究所","83; 1; 2",1,21

Ideone でテスト済み: http://ideone.com/fCgh7

于 2012-06-29T10:54:23.167 に答える
1

必要なものはこちら

String line = "Bosh,Mark,mark@gmail.com,\"3, Institute\",\"83, 1, 2\",1,21";
    Pattern regex = Pattern.compile("(\"[^\"]*\")");
    Matcher matcher = regex.matcher(line);
    while(matcher.find()){
        String replacedMatch = matcher.group();
        String gr1 = matcher.group(1);
        gr1.trim();
        replacedMatch = replacedMatch.replace(",", ";");
        line = line.replace(matcher.group(), replacedMatch);
    }

行には必要な値があります。

于 2012-06-29T10:21:40.307 に答える
0

RegExpを怠惰にしようとしましたか?別のアイデア:[]内でも「」を使用する必要があります。これを行うと、グローバルフラグが設定された期待どおりの出力が得られるはずです。

于 2012-06-29T09:59:26.600 に答える
0

あなたの正規表現は間違っています。「...」式の中に ] がないことを確認したいのはなぜですか? むしろ、正規表現を消極的にします (デフォルトは熱心です。これは、可能な限りキャッチすることを意味します)。

"(\"[^\\]]*\")"

する必要があります

"(\"[^\"]*\")"

しかし nhadtdh は正しいです。適切な CSV ライブラリを使用して解析し、 , to ; に置き換える必要があります。パーサーが返す値で。「Java CSV パーサー」をグーグルで検索すると、パーサーが見つかるはずです。

于 2012-06-29T10:01:55.727 に答える
0

代わりに正規表現を ("[^"]*") にするべきではありませんか? つまり、最初の行は次のようになります。

Pattern regex = Pattern.compile("(\"[^\"]*\")");

もちろん、これは、入力行の引用符で囲まれた値に引用符を使用できないことを前提としています。

于 2012-06-29T10:12:17.243 に答える