Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

regular expression for \" in java

I need to write a regular expression for string read from a file

apple,boy,cat,"dog,cat","time\" after\"noon"

I need to split it into

apple
boy
cat
dog,cat
time"after"noon

I tried using

Pattern pattern = 
Pattern.compile("[\\\"]");
String items[]=pattern.split(match);

for the second part but I could not get the right answer,can you help me with this?

like image 363
user1272855 Avatar asked Sep 19 '26 13:09

user1272855


1 Answers

Since your question is more of a parsing problem than a regex problem, here's another solution that will work:

public class CsvReader {

    Reader r;
    int row, col;
    boolean endOfRow;

    public CsvReader(Reader r){
        this.r = r instanceof BufferedReader ? r : new BufferedReader(r);
        this.row = -1;
        this.col = 0;
        this.endOfRow = true;
    }

    /**
     * Returns the next string in the input stream, or null when no input is left
     * @return
     * @throws IOException  
     */
    public String next() throws IOException {
        int i = r.read();
        if(i == -1)
            return null;

        if(this.endOfRow){
            this.row++;
            this.col = 0;
            this.endOfRow = false;
        } else {
            this.col++;
        }

        StringBuilder b = new StringBuilder();
outerLoop:  
        while(true){
            char c = (char) i;
            if(i == -1)
                break;
            if(c == ','){
                break;
            } else if(c == '\n'){
                endOfRow = true;
                break;
            } else if(c == '\\'){
                i = r.read();
                if(i == -1){
                    break;
                } else {
                    b.append((char)i);
                }
            } else if(c == '"'){
                while(true){
                    i = r.read();

                    if(i == -1){
                        break outerLoop;
                    }
                    c = (char)i;
                    if(c == '\\'){
                        i = r.read();
                        if(i == -1){
                            break outerLoop;
                        } else {
                            b.append((char)i);
                        }
                    } else if(c == '"'){
                        r.mark(2);
                        i = r.read();
                        if(i == '"'){
                            b.append('"');
                        } else {
                            r.reset();
                            break;
                        }
                    } else {
                        b.append(c);
                    }
                }
            } else {
                b.append(c);
            }
            i = r.read();
        }

        return b.toString().trim();
    }


    public int getColNum(){
        return col;
    }

    public int getRowNum(){
        return row;
    }

    public static void main(String[] args){

        try {
            String input = "apple,boy,cat,\"dog,cat\",\"time\\\" after\\\"noon\"\nquick\"fix\" hello, \"\"\"who's there?\"";
            System.out.println(input);
            Reader r = new StringReader(input);
            CsvReader csv = new CsvReader(r);
            String s;
            while((s = csv.next()) != null){
                System.out.println("R" + csv.getRowNum() + "C" + csv.getColNum() + ": " + s);
            }
        } catch(IOException e){
            e.printStackTrace();
        }
    }
}

Running this code, I get the output:

R0C0: apple
R0C1: boy
R0C2: cat
R0C3: dog,cat
R0C4: time" after"noon
R1C0: quickfix hello
R1C1: "who's there?

This should fit your needs pretty well.

A few disclaimers, though:

  • It won't catch errors in the syntax of the CSV format, such as an unescaped quotation mark in the middle of a value.
  • It won't perform any character conversion (such as converting "\n" to a newline character). Backslashes simply cause the following character to be treated literally, including other backslashes. (That should be easy enough to alter if you need additional functionality)
  • Some csv files escape quotes by doubling them rather than using a backslash, this code now looks for both.

Edit: Looked up the csv format, discovered there's no real standard, but updated my code to catch quotes escaped by doubling rather than backslashes.

Edit 2: Fixed. Should work as advertised now. Also modified it to test the tracking of row and column numbers.

like image 185
Captain Ford Avatar answered Sep 22 '26 10:09

Captain Ford



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!