2011-08-10 2 views
7

\ u003C와 같은 유니 코드 이스케이프 시퀀스가 ​​포함 된 텍스트가 있습니다.이 방법이 Ruby에서 유니 코드 이스케이프 시퀀스를 이스케이프 처리하지 못하게하는 가장 좋은 방법입니까?

string.gsub(/\u(....)/) {|m| [$1].pack("H*").unpack("n*").pack("U*")}

이 정확이 내가 그것을 언 이스케이프하는 해낸 무엇인가? (즉, 내 테스트에서 작동하는 것처럼 보이지만 더 지식이있는 사람이 문제를 발견 할 수 있습니까?)

+0

바로 당신입니다. 그것은 Rails의 ActiveSupport :: JSON에서 왔으며 ActiveSupport :: JSON으로 해독되었습니다. 그러나 이스케이프가 제대로 디코딩되지 않았습니다. (on Rails 2.1.2) –

답변

17

정규식 /\u(....)/에 몇 가지 문제가 있습니다. 모든

첫째, \u 당신이 오류가 발생합니다 1.8에서 그냥 당신이 찾고있는 \u 쌍보다는 하나의 u 일치합니다 1.9 당신이 생각했던 방법을 작동하지 않습니다; 당신이 원하는 \u 리터럴을 찾으려면 /\\u/을 사용해야합니다.

두 번째로, (....) 그룹은 지나치게 관용 적이기 때문에 4자를 통과 할 수 있으며 원하는 것은 아닙니다. 1.9에서는 (\h{4}) (4 자리 16 진수)를 원하지만, 1.8에서 ([\da-fA-F]{4})으로 \h이 필요합니다.

정규 표현식을 1.8과 1.9에서 모두 사용하려면 /\\u([\da-fA-F]{4})/을 사용해야합니다. 유니 코드 문자로 16 진수를 난도질하는 packunpack를 사용

>> s = 'Where is \u03bc pancakes \u03BD house? And u1123!' 
=> "Where is \\u03bc pancakes \\u03BD house? And u1123!" 
>> s.gsub(/\\u([\da-fA-F]{4})/) {|m| [$1].pack("H*").unpack("n*").pack("U*")} 
=> "Where is μ pancakes ν house? And u1123!" 

아마 충분하지만 더 나은 방법이있을 수있다 : 이것은 당신이 1.8 및 1.9에 다음을 제공합니다.

+1

이것을 String 클래스의 확장으로 추가하는 것도 유용 할 수 있습니다 (String # utf8_decode를 사용했습니다). – Mikey

관련 문제