문제

이제 두 가지 문제가 있습니다. 하지만 나는 재미있다!

나는 시작했다 이 조언 시도하고 나누는 것이 아니라 허용 가능한 필드와 일치 하고이 표현으로 확장됩니다.

final Pattern pattern = Pattern.compile("\"([^\"]*)\"|(?<=,|^)([^,]*)(?=,|$)");

성가신 탈출 된 인용문없이 표현식은 다음과 같습니다.

"([^"]*)"|(?<=,|^)([^,]*)(?=,|$)

이것은 나에게 잘 작동합니다. "두 인용문과 그들 사이의 모든 것"에서 일치하거나 "선의 시작 또는 쉼표와 줄 또는 쉼표의 끝"과 일치합니다. 경기를 반복하면 비어 있더라도 모든 필드가됩니다. 예를 들어,

the quick, "brown, fox jumps", over, "the",,"lazy dog"

분해합니다

the quick
"brown, fox jumps"
over
"the"

"lazy dog"

엄청난! 이제 나는 인용문을 떨어 뜨리고 싶다. 그래서 나는 commas를 위해하고있는 것처럼 lookahead를 추가하고 캡틴을 캡처하지 않는 그룹을 추가했다.

final Pattern pattern = Pattern.compile("(?<=\")([^\"]*)(?=\")|(?<=,|^)([^,]*)(?=,|$)");

다시 표현은 다음과 같습니다.

(?<=")([^"]*)(?=")|(?<=,|^)([^,]*)(?=,|$)

원하는 결과 대신

the quick
brown, fox jumps
over
the

lazy dog

이제이 분류를 얻습니다.

the quick
"brown
 fox jumps"
,over,
"the"
,,
"lazy dog"

내가 무엇을 놓치고 있습니까?

도움이 되었습니까?

해결책

연산자 우선 순위. 기본적으로 아무것도 없습니다. 모두 왼쪽에서 오른쪽입니다. 그래서 또는 (|)는 마감 견적 룩 하이드와 쉼표 룩 하이드에 적용됩니다.

노력하다:

(?:(?<=")([^"]*)(?="))|(?<=,|^)([^,]*)(?=,|$)

다른 팁

(?:^|,)\s*(?:(?:(?=")"([^"].*?)")|(?:(?!")(.*?)))(?=,|$)

이것은 당신이 원하는 것을해야합니다.

설명:

(?:^|,)\s*

패턴은 문자열의 시작으로 시작해야합니다. 또한 처음에 모든 공백을 무시하십시오.

봐, 나머지는 인용문으로 시작하는지 확인

(?:(?=")"([^"].*?)")

그렇다면 다음 인용문까지 인사하지 않게 일치시킵니다.

(?:(?!")(.*?))

인용문으로 시작하지 않으면 다음 쉼표 또는 문자열 끝까지 인사하지 않게 일치시킵니다.

(?=,|$)

패턴은 쉼표 또는 문자열 끝으로 끝나야합니다.

내가 잘못한 일을 이해하기 시작했을 때, 나는 또한 룩 어라운드가 어떻게이를 만들고 있는지 이해하기 시작했습니다. 나는 마침내 일치하는 모든 텍스트를 원하지 않는다는 것을 깨달았습니다. 그 안에 특정 그룹을 원했습니다. 나는 폐쇄 쉼표에 대해 전망대를 작성하지 않았다는 점을 제외하고는 원래 동정형과 매우 유사한 것을 사용하게되었습니다. 여기 내 최종 코드가 있습니다.

package regex.parser;

import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CSVParser {

    /*
     * This Pattern will match on either quoted text or text between commas, including
     * whitespace, and accounting for beginning and end of line.
     */
    private final Pattern csvPattern = Pattern.compile("\"([^\"]*)\"|(?<=,|^)([^,]*)(?:,|$)");  
    private ArrayList<String> allMatches = null;    
    private Matcher matcher = null;
    private String match = null;
    private int size;

    public CSVParser() {        
        allMatches = new ArrayList<String>();
        matcher = null;
        match = null;
    }

    public String[] parse(String csvLine) {
        matcher = csvPattern.matcher(csvLine);
        allMatches.clear();
        String match;
        while (matcher.find()) {
            match = matcher.group(1);
            if (match!=null) {
                allMatches.add(match);
            }
            else {
                allMatches.add(matcher.group(2));
            }
        }

        size = allMatches.size();       
        if (size > 0) {
            return allMatches.toArray(new String[size]);
        }
        else {
            return new String[0];
        }           
    }   

    public static void main(String[] args) {        
        String lineinput = "the quick,\"brown, fox jumps\",over,\"the\",,\"lazy dog\"";

        CSVParser myCSV = new CSVParser();
        System.out.println("Testing CSVParser with: \n " + lineinput);
        for (String s : myCSV.parse(lineinput)) {
            System.out.println(s);
        }
    }

}

나는 이것이 OP가 원하는 것이 아니라는 것을 알고 있지만, 다른 독자들에게는 String.replace 메소드를 사용하여 OPS Current Regex의 결과 배열에서 각 요소의 인용문을 제거하는 데 사용될 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top