시작 큰따옴표와 끝나는 큰따옴표가 누락된 것과 일치하는 정규식

시작 큰따옴표와 끝나는 큰따옴표가 누락된 것과 일치하는 정규식

파이프( )로 구분된 대용량(2,500만 행) 데이터 파일이 있습니다 |. 데이터 공급업체에서 파일을 제공하고 저는 자동화된 작업을 실행하여 파일을 Redshift 데이터베이스에 로드한 다음 데이터를 처리합니다.

다음은 데이터 샘플입니다.

123|110092|ACCT|"HC Account"|"Account1||||||||||||"Mary"|||"|"||||132|"STE|504"|1253|Unspecified Account|||N||ACTV|Active||||04/30/2013|12/31/2099|||||||||||||

지금까지 내가 본 필드 데이터에는 세 가지 세트가 있습니다.

  1. 텍스트 필드는 큰따옴표( ")로 묶입니다. 예: "HC Account", "Mary""|". 이는 정확하며 데이터는 따옴표 없이 로드되어야 합니다.
  2. 일부 값에는 파이프 구분 기호가 포함됩니다. 예를 들어: "STE|504". 이 경우 필드를 반드시 큰따옴표로 묶어야 합니다. 그렇지 않은 경우 아래 카테고리 3에 속합니다.
  3. 때로는 시작 인용문만 제공되고 종료 인용문이 없는 경우도 있습니다. 예를 들어: "Account1.

핵심요약: 로 시작하는 모든 필드는 |"으로 끝나야 합니다 "|. 그렇지 않고 다른 것이 |"발견되면 첫 번째 큰따옴표를 이스케이프해야 합니다.

따라서 내 데이터 행은 Unix/Python/기타 제안에서 전처리한 후 다음과 같이 편집되어야 합니다.

123|110092|ACCT|"HC Account"|"Account1||||||||||||"Mary"|||"|"||||132|"STE|504"|1253|Unspecified Account|||N||ACTV|Active||||04/30/2013|12/31/2099|||||||||||||


SED를 사용하여 파일을 수정하기 위해 Unix 스크립트를 작성할 계획입니다. 지금까지 작성한 정규식은 다음과 같습니다.

(\|")(?!([a-zA-Z0-9]|\s|\||\/)*("\|))

그러나 이는 문자열을 올바르게 일치시키지 못합니다.

제가 테스트하고 있는 링크는 다음과 같습니다.https://regexr.com/3toib

평균 파일 크기가 3~5GB이고 일반적으로 이러한 파일이 여러 개(10개 이상) 있기 때문에 코드를 가볍게 유지하고 싶습니다.

PS Redshift는 Postgre SQL 엔진을 사용하는 AWS 데이터베이스 서비스이며 적절하게 인용된 필드에서 인용을 제거하고 \.

또한 코드가 가볍기 때문에 Python/다른 스크립팅 언어로 이 작업을 수행할 의향이 있습니다.

답변1

데이터에 대해 제공한 사양에는 한 가지 큰 문제가 있습니다. 가 유효한 문자열 이거나 "|"더 정확하게는 따옴표 붙은 문자열이 파이프로 시작할 수 있는 경우 끝 따옴표가 누락된 문자열(예: )에 "Account1파이프로 시작하는 첫 번째 따옴표 붙은 필드가 있는 경우(예: "|Mary") 결정할 방법이 없다모든 경우에"|가 의 끝 인용문 |"Account1||||||||||||"|이거나 의 시작 인용문인 경우 |"|Mary"|.

예를 들어, 가독성을 위해 약간 수정된 단축 버전의 데이터를 사용하면 두 번째부터 인용된 모든 문자열이 파이프로 시작하고 끝 인용문이 누락됩니다.

123|110092|ACCT|"HC Account"|"Account1||||||||||||"|Mary|||"|||||132|"|STE|504|1253

이는 다음과 같이 잘못 해석될 수 있음을 알 수 있습니다.

123 110092 ACCT "HC Account" "Account1||||||||||||" Mary   "|||||132|" STE 504 1253

이는 정규 표현식, Python 또는 다른 언어를 사용하는 경우 문제가 됩니다. 일반적인 경우의 문제~할 수 있다"해결"할 수 있지만 복잡하며 행당 존재하는 필드 수와 해당 필드의 데이터 구조에 대한 지식을 사용해야 합니다. (그리고 항상 처리되지 않은 극단적인 경우가 있을 수 있습니다.)


즉, 적어도 감지하는 정규식 솔루션은 다음과 같습니다.최대여는 큰 따옴표에서 닫는 따옴표가 누락된 경우 정규식은 각 줄의 시작 부분부터 처리되지 않은 일치하지 않는 첫 번째 여는 따옴표까지 모든 텍스트를 캡처해야 하므로 다중 패스 접근 방식이 필요합니다. (그렇지 않으면 정규식에서 알 수 있듯이 가장 단순한 경우에도 거짓 긍정이 발견됩니다.)

필요한 패스 수는 전체 파일의 행에 대한 여는 따옴표 전용 필드의 최대 수에 1을 더한 것입니다. 각 파일의 처리를 종료하려면 정규 표현식이 파일을 더 이상 수정하지 않는 시기를 감지해야 합니다.

이것은 대부분의 경우에 작동하는 가장 간단한 정규식입니다.

                    Capturing Group 1           Capturing Group 2
               (All previous valid fields)  (Unclosed opening quote)
  __________________________|_________________________  |
 |                                                    || |
^((?:(?:(?!")[^|\r\n]*|"[^"\r\n]*"(?=$|\|))(?:$|\|))*+)(")
        |____________| |_________________| |______|
              |                 |              |
      Unquoted field  OR  Quoted field     EOL or hypen delimiter

다음 대체 문자열과 함께 사용하세요.

$1\\$2

데모

관련 정보