Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > как заставить игнорировать разделитель в кавычках


Автор: integral 15.8.2008, 16:17
Хочу что бы StringTokenizer получал из строки "\"TYU\",\"sdf,123\"" две строки  TYU и  sdf,123
А он возращает 3 
Код

new StringTokenizer("\"TYU\",\"sdf,123\"", ",");

Как записать правильно? или может нуженг другой способ а не StringTokenizer?

Автор: alexadr 15.8.2008, 17:27
Я так понимаю, что конечная задача написать парсер CSV файлов?! (это я сужу по тестовой строке в примере)

Автор: integral 15.8.2008, 17:33
несовсем, нужно розпарсить одну тока строку в таком формате.
полазив по исходникам файлов, я нашел отличный парсер (мод. вариант):
Код

    private static String[] parseLine(String nextLine) throws IOException {
        char quotechar = '"';
        char separator = ',';
        if (nextLine == null) {
            return null;
        }
         
        ArrayList tokensOnThisLine = new ArrayList();
        StringBuffer sb = new StringBuffer();
        boolean inQuotes = false;
        do {
            if (inQuotes) {
                // continuing a quoted section, reappend newline
                sb.append("\n");
                nextLine = null;
                if (nextLine == null)
                 break;
                }
                for (int i = 0; i < nextLine.length(); i++) {
         
                char c = nextLine.charAt(i);
                if (c == quotechar) {
                // this gets complex... the quote may end a quoted block, or escape another quote.
                // do a 1-char lookahead:
                if( inQuotes  // we are in quotes, therefore there can be escaped quotes in here.
                     && nextLine.length() > (i+1)  // there is indeed another character to check.
                        && nextLine.charAt(i+1) == quotechar ){ // ..and that char. is a quote also.
                        // we have two quote chars in a row == one quote char, so consume them both and
                        // put one on the token. we do *not* exit the quoted text.
                         sb.append(nextLine.charAt(i+1));
                          i++;
                        }else{
                         inQuotes = !inQuotes;
                          // the tricky case of an embedded quote in the middle: a,bc"d"ef,g
                          if(i>2 //not on the begining of the line
                                  && nextLine.charAt(i-1) != separator //not at the begining of an escape sequence
                                  && nextLine.length()>(i+1) &&
                                  nextLine.charAt(i+1) != separator //not at the    end of an escape sequence
                          ){
                              sb.append(c);
                          }
                        }
                 } else if (c == separator && !inQuotes) {
                  tokensOnThisLine.add(sb.toString());
                  sb = new StringBuffer(); // start work on next token
                 } else {
                  sb.append(c);
                 }
            }
        } while (inQuotes);
        tokensOnThisLine.add(sb.toString());
        return (String[]) tokensOnThisLine.toArray(new String[0]);
    }


оригинал был взят с http://opencsv.svn.sourceforge.net/viewvc/opencsv/trunk/src/au/com/bytecode/opencsv/CSVReader.java?revision=15&view=markup

так что тема закрыта, спасиба

Автор: Ortega 18.8.2008, 09:26
А не проще ли попробовать регулярку?
Код

        String source = "\"TYU\",\"sdf,123\"";
        String regex = "[^\",\"]+";
        Matcher m = Pattern.compile(regex).matcher(source);
        while(m.find()) {
            System.out.println(m.group());
        }

По-моему, так компактнее ;)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)