0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

正規表現を使って、データがダブルクォーテーションで囲まれているCSVファイルを読み込む

Posted at

概要

  • 例:データにカンマや改行(LFやCR)が含まれているとき、ダブルクォーテーションで囲うことでそれらを取り扱えるようにした場合…のCSVファイルの読み込みをしたい。
  • 単純に,で区切りたいところですが、要素に"ぶっかけ,混ぜ混ぜ派"のように,が含まれている可能性があるので、正規表現を使って分割します。
  • 今回の要件にあう正規表現は以下の通り
\"([^\"]*)\"

サンプルデータの作成

なんちゃって個人情報を利用してサンプルデータを作成。

"ぶっかけ,混ぜ混ぜ派"のように、各行最後の要素に,を入れてテスト。

dummy.csv
"森下 優","もりした ゆう","morishita_yuu@example.com","女","73","1945/8/6","既婚","福島県","080- 141-4402","au","ぶっかけ,混ぜ混ぜ派"
"関口 啓介","せきぐち けいすけ","sekiguchi_keisuke@example.com","男","26","1993/1/24","既婚","東京都","090-3212-8148","au","ぶっかけ,せき止め派"
"谷村 雄太","たにむら ゆうた","tanimura_yuuta@example.com","男","51","1967/8/23","既婚","愛知県","080-6212-5174","ドコモ","手前ルー,混ぜ混ぜ派"

コード

呼び出し側
    NSArray *usersInfo = [self loadCsvFileWithDoubleQuotes:[NSURL fileURLWithPath:@"/Users/dummy.csv"]];
    // 結果確認
    for (NSArray *userInfo in usersInfo) {
        NSLog(@"%@", [NSString stringWithCString:[userInfo.description cStringUsingEncoding:NSASCIIStringEncoding] encoding:NSNonLossyASCIIStringEncoding]);
    }
関数
/**
 @brief 各要素がダブルコーテーションで囲まれたCSVファイルの内容を取得する
 @param csvURL 対象CSVのパス
 @return カンマで分けられた要素配列(ダブルコーテーションを除く)
 @warning Encoding=UTF8
 読み込み失敗時は空配列を返す
 */
- (NSArray *)loadCsvFileWithDoubleQuotes:(NSURL *)csvURL {
    NSError  *loadError     = nil;
    // CSVファイルの読み込み
    NSString *csvContents   = [[NSString alloc] initWithContentsOfURL:csvURL
                                                             encoding:NSUTF8StringEncoding
                                                                error:&loadError];
    if (loadError) {
        NSLog(@"%@", [loadError localizedDescription]);
        return @[];
    }
    // 正規表現を使ってカンマ区切りで各要素に分解し読み込み
    NSMutableArray *extractWholeResult = [NSMutableArray array];    // 全体の抽出結果
    NSRegularExpression *reg = [[NSRegularExpression alloc] initWithPattern:@"\"([^\"]*)\"" options:0 error:nil];   // ダブルコーテーションに囲まれた部分を抽出する
    [csvContents enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) {
        NSArray *matches = [reg matchesInString:line options:0 range:NSMakeRange(0, [line length])];
        NSMutableArray *extractResult = [[NSMutableArray alloc] init];    // 行ごとの抽出結果
        for (NSTextCheckingResult *result in matches) {
            for (int i = 1; i < [result numberOfRanges]; i++) {
                NSRange r = [result rangeAtIndex:i];
                [extractResult addObject:[line substringWithRange:r]];
            }
        }
        [extractWholeResult addObject: extractResult];
    }];
    return extractWholeResult;
}
ログ出力
2019-02-05 10:12:58.803886+0900 ExtractWithRegularExpression[86252:3480833] (
    "森下 優",
    "もりした ゆう",
    "morishita_yuu@example.com",
    "女",
    73,
    "1945/8/6",
    "既婚",
    "福島県",
    "080- 141-4402",
    au,
    "ぶっかけ,混ぜ混ぜ派"
)
2019-02-05 10:12:58.803940+0900 ExtractWithRegularExpression[86252:3480833] (
    "関口 啓介",
    "せきぐち けいすけ",
    "sekiguchi_keisuke@example.com",
    "男",
    26,
    "1993/1/24",
    "既婚",
    "東京都",
    "090-3212-8148",
    au,
    "ぶっかけ,せき止め派"
)
2019-02-05 10:12:58.803968+0900 ExtractWithRegularExpression[86252:3480833] (
    "谷村 雄太",
    "たにむら ゆうた",
    "tanimura_yuuta@example.com",
    "男",
    51,
    "1967/8/23",
    "既婚",
    "愛知県",
    "080-6212-5174",
    "ドコモ",
    "手前ルー,混ぜ混ぜ派"
)

ライフハックなやり方(邪道ですね)

","で componentsSeparatedByString をして、冒頭と末尾のダブルコーテーションを取ってやる。

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?