Как построить регулярное выражение для анализа значений, разделенных запятыми, но игнорировать запятую в двойных кавычках? - PullRequest
3 голосов
/ 10 марта 2011

Пример строки:

2011-03-09,4919 1281 0410 9930,55107,SAZB2314,"John, Doe" ,1-888-888-4452 ext 1813

Необходимо отметить все запятые, но не одну в двойных кавычках.

Ответы [ 7 ]

17 голосов
/ 10 марта 2011

Вы можете использовать Text::CSV от CPAN.

10 голосов
/ 10 марта 2011

Или используйте Text :: CSV_XS , который делает то же самое, но быстрее.

1 голос
/ 11 марта 2011

Использование Данные :: Запись .

0 голосов
/ 18 февраля 2013

В настоящее время я работаю над проектом, и это регулярное выражение помогло мне для файла CSV точно в том же формате.

("([^"]*)",?)|(([^",]*),?)

Это не будет работать, если одна запись случайно разбита на несколько строк. У меня была эта проблема, и я решил ее, выяснив, правильно ли было подсчет непустых совпадений.

0 голосов
/ 20 августа 2012

Я знаю, как это сделать на Java. Регулярные выражения могут работать по-разному в PERL, но позвольте мне показать идею. Существует объединение из 3 пунктов.

// 1) select any quoted text before comma
// if it fails then
// 2) select any text before comma
// if it also fails then
// 3) select any text before end of the input

final String OR           = "|";
final String QUOTE        = "\"[\\s]*"; //with trailing whitespaces
final String NON_QUOTES   = "[^\"]*";
final String COMMA        = ",";
final String NON_COMMA    = "[^,]*"; 
final String NON_END      = "[^$]+"; 
final String END          = "$";

final Pattern p = Pattern.compile(
QUOTE+NON_QUOTES+QUOTE+COMMA+
OR+
NON_COMMA+COMMA+
OR+
NON_END+END);

Это даст вам совпадения, которые, к сожалению, будут заканчиваться запятой, кроме последней. Не существует групп захвата, потому что нет смысла определять их с помощью предложения union следующим образом.

0 голосов
/ 11 марта 2011

Попробуйте:

use strict;
use warnings;
use Text::ParseWords;

while (<DATA>) {
    chomp;
    my @f = quotewords ',', 0, $_;
    for (@f) {
            s/^\s*|\s*$//g;
            s/^/"/ && s/$/"/ if /,/;
    }
    print join (",", @f), "\n";
}

__DATA__
2011-03-09,4919 1281 0410 9930,55107,SAZB2314,"John, Doe" ,1-888-888-4452 ext 1813
"ashish", "kumar", "test,1", "test2"
"foo", "b,ar", "msg1", "msg2"
0 голосов
/ 10 марта 2011

Если вам нужно регулярное выражение, а не правильный синтаксический анализатор, как предлагает @eugene y, вот одна попытка.Захваты должны возвращать элементы списка по порядку.

(?:(?:([^"]*?|".*?"),)*([^"]*?|".*?"))?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...