2013-11-20 4 views
0

Я читаю файл построчно в жало и разбить его на более мелкие строки с помощью line.indexOf('"', 1) и substring() , но этот способ не обнаруживает ли, прежде чем " является \ или нет, чтобы он не реагировать на побег. как я могу это решить?маскирующего использование IndexOf()

(я не могу просто использовать line.split('"') Couse " оба на начало и конец подстроки, ни расколоть другим полукокса, потому что моя задача не позволяет так.)

весь сегмент чтение:

while ((line = bufferedReader.readLine()) != null) { 
     System.out.println(line); 
     while(line.length()>0){ 
      if(line.charAt(0) == ',' || line.charAt(0) == ' '){ 
       line = line.substring(1); 
      } 
      else{ 
       if(line.indexOf(',') != -1){ 
        if (line.charAt(0) == '"'){ 
        pabaiga = line.indexOf("\"", 1); 
        zodis = line.substring(0, pabaiga+1); 
        line = line.substring(pabaiga+1); 
        duomenys.add(zodis); 
        } 
        else{ 
         pabaiga = line.indexOf(','); 
         zodis = line.substring(0, pabaiga); 
         line = line.substring(pabaiga); 
         duomenys.add(zodis); 
        } 
       } 
       else{ 
        zodis = line; 
        line = line.substring(line.length()); 
        duomenys.add(zodis); 
       } 
      } 
      for(String elem : duomenys){ 
      System.out.println(elem); 
      } 
duomenys.removeAll(duomenys); 
     } 

Мне не разрешалось разделять только разделителем, так как в середине строки может быть один, используя \, в текстовом файле не вариант. Поэтому мне было предложено определить один элемент sting как «текст», но если он содержит другое «или» в середине, мой текущий код не работает.

если моя строка из текстового файла "start \"title\" end", 10, 20, "text"
массив жала должен содержать

  • [0] "start "title" end"
  • [1] 10
  • [2] 20
  • [3] "text"
+1

Просьба привести пример ввода. Я предполагаю, что вы можете «разбить», поскольку он требует регулярное выражение. –

+0

Используйте регулярное выражение для решения вашей проблемы. Вы можете определить отрицательное выражение регулярного выражения tha t соответствует только тогда, когда предыдущий символ не является обратным слэшем (\) – sjkm

+0

Пожалуйста, [[edit]] ваш вопрос с несколькими примерами ввода и ожидаемого вывода, потому что теперь ваш вопрос не совсем ясен о том, чего вы пытаетесь достичь. – Pshemo

ответ

-1

Если Вы хотите, чтобы последний индекс затем просто использовать LastIndexOf

.lastindexOf("\"", 1) 

Просто замените

pabaiga = line.indexOf("\"", 1); 

с

pabaiga = line.lastindexOf("\"", 1); 
+0

OP хочет найти индекс для первого '' '**, которому не предшествует **' \\ '. Т.е. первая _unescaped_ quote. Это не решает этого. –

+0

@BoristheSpider Я думаю, он ищет вторую «чтобы он мог найти конец линии. Исправьте меня, если я ошибаюсь OP – user1210093

+0

Борис Паук сказал, что я хотел, я отредактировал мой вопрос, может быть, теперь более очистительно – user2542809

0

Вы можете хранить свои первые маркеры в динамическом компоненте размера как List. Чтобы заполнить такой список вашими жетонами, вам нужно перебирать каждый символ в вашем предложении, и если он не является ,, который находится внутри цитаты, то добавьте его в tokenBuilder, но если эта запятая находится вне цитаты, добавьте текущее значение tokenBuilder в ваш токен-лист. Вот пример кода.

String line = "\"start \\\"title\\\" end\", 10, 20, \"text\""; 

List<String> tokens = new ArrayList<>(); 
StringBuilder tokenBuilder = new StringBuilder(); 

boolean insideQuote = false; 
char ch, prev = ' '; 

for (int i = 0; i < line.length(); i++) { 
    ch = line.charAt(i); 
    if (ch == '"' && prev != '\\') {// normal " (without \ before) 
     insideQuote = !insideQuote; // starts or ends quotation 
    } 
    // commas that are outside quote or last character in line 
    // should invoke adding non-empty builder to list 
    if (ch == ',' && !insideQuote || i == line.length() - 1) { 
     if (tokenBuilder.length() > 0) { 
      tokens.add(tokenBuilder.toString().trim()); 
      tokenBuilder.delete(0, tokenBuilder.capacity()); 
     } 

    } 
    // add every character to builder except \ that are inside 
    // quotes and have " after it 
    else if (!(ch == '\\' && i + 1 < line.length() 
      && line.charAt(i + 1) == '"' && insideQuote)) { 
     tokenBuilder.append(ch); 
    } 
    prev = ch;//in next loop previous character should be our current one 
} 

String[] array = tokens.toArray(new String[tokens.size()]); 

for (String s : array) 
    System.out.println(">" + s); 

Выход:

>"start "title" end" 
>10 
>20 
>"text 
+0

. В этом проблема заключается в том, что где может быть запятая в середине строки, и ее следует рассматривать как часть строки, если она находится между двойными кавычками. – user2542809

+0

@ user2542809 проверить мой обновленный ответ. – Pshemo

0

Вы могли бы использовать это (онлайн пример в http://ideone.com/TTtlZV):

import java.util.*; 
import java.lang.*; 
import java.io.*; 

/* Name of the class has to be "Main" only if the class is public. */ 
class Ideone 
{ 
public static void main (String[] args) throws java.lang.Exception 
    { 
     boolean inQuoted = false; 

     List<String> parts = new ArrayList<String>(); 
     String s = "\"start \\\"title\\\" end\", 10, 20, \"text\""; 
     StringBuilder current = new StringBuilder(); 
     for(int i=0; i<s.length(); i++){ 
      char c = s.charAt(i); 
      char cPrev = (i == 0 ? (char)0 : s.charAt(i-1)); 

      if(c == '"' && cPrev != '\\'){ 
       inQuoted = !inQuoted; 
      } 

      if(c == ',' && !inQuoted){ 
       if(current.length() > 0){ 
        parts.add(current.toString()); 
        current = new StringBuilder(); 
       } 
      } 
      else { 
       int length = current.length(); 
       if(length > 1 && c == '"' && current.charAt(length-1) == '\\'){ 
        current.deleteCharAt(length-1); 
       } 
       current.append(c); 
      } 
     } 
     if(current.length() > 0){ 
      parts.add(current.toString()); 
     } 

     System.out.println(parts); 
    } 
} 

Это не будет обрабатывать двойное экранирование.Например

\\ "

Если я запускаю эту программу выход:

[ "старт \" название \" конец», 10, 20, "текст" ]

Смежные вопросы