program tip

csv 데이터를 가져올 때 "UTF-8에서 잘못된 바이트 시퀀스"를 제거하는 방법

radiobox 2020. 12. 3. 07:43
반응형

csv 데이터를 가져올 때 "UTF-8에서 잘못된 바이트 시퀀스"를 제거하는 방법


사용자가 csv를 통해 데이터를 가져올 수 있습니다 (루비 1.9.2를 사용하므로 csv가 더 빠름).

물론 사용자 데이터이므로 제대로 삭제되지 않을 수 있습니다.

/ index 메소드에 데이터를 표시하려고 할 때 가끔 필드 widget.name 중 하나를 표시하는 erb를 가리키는 "UTF-8의 유효하지 않은 바이트 시퀀스"오류가 발생합니다.

가져 오기를 할 때 들어오는 데이터가 유효하도록 강제하고 싶습니다. 문자열을 유효한 utf8 문자열에 매핑하는 루비 연산자가 있습니까?

goodstring = badstring.no_more_invalid_bytes

'잘못된'데이터의 한 예는 하이픈처럼 보이지만 일반 아스키 하이픈이 아닌 문자입니다. 우리는 UTF-8이 아닌 문자를 합리적인 ascii 등가물에 매핑하는 것을 선호하지만 (예 : u는 u로 이동) 문자를 간단히 제거해도 괜찮습니다.

이것은 많은 데이터를 가져올 때이기 때문에 빠른 내장 연산자가 필요합니다.


참고 : 다음은 데이터의 예입니다. 이 파일은 Windows 형식으로 제공되며 8 비트 ASCII입니다. 임포트하고 erb에서 widget.name.inspect를 표시합니다 (widget.name 대신). "Chains \ x96 Accessories"

따라서 데이터의 한 예는 실제로 8 비트 코드 96 인 "하이픈"입니다.

--- csv 구문 분석을 변경하여 fldval = d.encode ( 'UTF-8') 할당하면 다음 오류가 발생합니다.

Encoding::UndefinedConversionError in StoresController#importfinderitems
"\x96" from ASCII-8BIT to UTF-8

우리가 찾고있는 것은 단순히 비 ASCII를 제거하더라도 원본 유형에 관계없이 유효한 utf8이되도록 강제하는 간단한 방법입니다.


인코딩을 강제하는 것만 큼 '좋은'것은 아니지만 가져 오기 시간에 약간의 비용이 들지만 d.to_s.strip.gsub (/ \ P {ASCII} /, '') 감사합니다, Mladen!


Ruby 1.9 CSV에는 m17n에서 작동하는 새로운 파서가 있습니다. 파서는 문자열에서 IO 개체의 인코딩과 함께 작동합니다. 다음 방법 : 인코딩을 지정할 수 ::foreach, ::open, ::read, and ::readlines있는 선택적 옵션 :encoding사용할 수 있습니다 .

예를 들면 :

CSV.read('/path/to/file', :encoding => 'windows-1251:utf-8')

모든 문자열을 UTF-8로 변환합니다.

또한 표준 인코딩 이름 'ISO-8859-1'을 사용할 수 있습니다.

CSV.read('/..', {:headers => true, :col_sep => ';', :encoding => 'ISO-8859-1'})

비 UTF-8 인코딩으로 1.9.2에서 외부 파일을 읽는 것과 관련된 유사한 질문에 대답했습니다. 그 대답이 많은 도움이 될 것이라고 생각합니다 : Rails v3 / Ruby 1.9.2의 문자 인코딩 문제

안정적으로 변환하려면 소스 인코딩을 알아야합니다. 이것을 결정하는 데 도움이되는 다른 답변에서 링크 한 것과 같은 라이브러리가 있습니다.

또한 파일에서 데이터를로드하지 않는 경우 1.9.2에서 문자열 인코딩을 매우 쉽게 변환 할 수 있습니다.

'string'.encode('UTF-8')

그러나 다른 인코딩으로 문자열을 작성하는 경우는 드뭅니다. 가능하면 해당 문자열을 환경으로 읽을 때 변환하는 것이 가장 좋습니다.


CSV.parse(File.read('/path/to/csv').scrub)

Ruby 1.9는 잘못된 감지 및 교체로 문자열 인코딩을 변경할 수 있습니다.

str = str.encode('UTF-8', :invalid => :replace)

인코딩을 알 수없는 파일에서로드 된 문자열과 같은 비정상적인 문자열의 경우 정규식, #gsub 또는 #delete 대신 #encode를 사용하는 것이 좋습니다. 이러한 문자열은 모두 구문 분석 할 문자열이 필요하기 때문입니다.하지만 문자열이 깨지면 구문 분석 할 수 없으므로 해당 메서드가 실패합니다.

다음과 같은 메시지가 표시되는 경우 :

error ** from ASCII-8BIT to UTF-8

그런 다음 이미 UTF-8로 된 바이너리 문자열을 변환하려고 시도하고 있으며 UTF-8을 강제 실행할 수 있습니다.

str.force_encoding('UTF-8')

원래 문자열이 이진 UTF-8이 아니거나 출력 문자열에 잘못된 문자가있는 경우 Ruby 인코딩 음역을 읽어보십시오.


Rails 를 사용 하는 경우 다음과 같이 수정할 수 있습니다.

'Your string with strange stuff #@~'.mb_chars.tidy_bytes

잘못된 utf-8 문자를 제거하고 유효한 문자로 바꿉니다. 더 많은 정보 : https://apidock.com/rails/String/mb_chars


CSV 파일을 Google 문서 스프레드 시트에 업로드하고 CSV 파일로 다시 다운로드합니다. 수입과 짜잔! (내 경우에서 일함)

아마도 Google은 원하는 형식으로 변환합니다 ..

출처 : UTF-8 인코딩을 사용하는 Excel에서 CSV로


이만 해

anyobject.to_csv(:encoding => 'utf-8')

다른 사람이 언급했듯이 스크럽은 Ruby 2.1 이상에서이를 정리하는 데 효과적입니다. 큰 파일이있는 경우 전체 내용을 메모리로 읽고 싶지 않을 수 있으므로 다음과 같이 스크럽을 사용할 수 있습니다.

data = IO::read(file_path).scrub("")
CSV.parse(data, :col_sep => ',', :headers => true)  do |row|
   puts row
end

참고URL : https://stackoverflow.com/questions/5053216/when-we-import-csv-data-how-eliminate-invalid-byte-sequence-in-utf-8

반응형