2014-06-22 5 views
2

사전 이스케이프 된 따옴표를 포함 할 수있는 문자열에서 큰 따옴표를 이스케이프 처리하는 코드가 있습니다. 예컨대 : 루비 1.8.7p374에 다음 코드를 사용하여Ruby가이 패턴의 두 번째 발생을 대체하지 않는 이유는 무엇입니까?

This is a \"string" 

: ab""c =>ab\""c을 다음 문자열을하려고 할 때

string.gsub!(/([^\\])"/, '\1\"') 

그러나, 좀 재미 가장자리의 경우를 얻을. 나는 그것이 양쪽 따옴표를 벗어나기를 기대할 것이다.

큰 문제는 아니지만 궁금합니다.
내 표현이 실수입니까? A gsub 버그/기능?

(최신 루비 버전에서는 음수 룩백을 사용하여 쉽게 해결할 수 있지만이 버전에서는 지원되지 않는 것 같습니다).

+0

문제가 중복되어'([^ \\])'이 방금 교체 한'''과 일치하지 않습니다. –

+0

당신이 가지고있는 것이 명확하지 않습니다. 끝에''' '\ "'로 이스케이프 된 것으로 설명 될 것입니다. 그러나 그 전에'\"는 역 슬래시 문자 뒤에 큰 따옴표 문자가 오는 것을 의미합니다.이 문자는'\\ \ "도망 칠 때. 이것이 정말로 당신이 가지고있는 것입니까? – sawa

답변

2

견적가에있는 경우 귀하의 정규식도 작동하지 않습니다 문자열 시작 예 :"ab""c"ab\""c으로 변환됩니다. 그 이유는 큰 따옴표를 사용하는 경우와 비슷합니다.

gsubb"과 일치하고이를 바꿔 넣은 후 마지막 일치에서 다음으로 보며 다음에 오는 "을보고 있지만 이전에 소비 한 문자는 보지 않습니다.

최신 Ruby 버전에서 보이는 문제로 문제를 해결할 수는 있지만 문제가있는 문자열 문제가 해결되지는 않습니다. 이 문제를 해결하는 방법은 \G anchor (Ruby 1.8.7에서 사용 가능)을 사용하는 것입니다.이 방법은 이전 일치 항목이 끝난 위치 또는 문자열 시작 부분과 일치합니다. 따라서 또는이 현재 일치 항목의 시작 부분에있는 것입니다. 즉, "이 방금 일치했거나 문자열의 시작 부분에 있음을 나타냅니다.이런 식으로 뭔가 :이 \"ab\"\"c에 문자열을 "ab""c 변환합니다

string.gsub!(/([^\\]|\G)"/, '\1\"') 

.

+0

나는이 앵커에 대해 전혀 몰랐습니다. 아주 멋진 답변입니다! – GeReV

3

\ 문자가 아닌 문자와 일치하는 것이 필요하다면 정규 표현식은 이어야하며 그 문자와 따옴표는 모두이어야합니다. 일치하는 gsub도 겹칠 수 없습니다.

당신은 룩앤지 (look-behind) 어설 션으로이 문제를 해결할 수 있습니다. 그러나 이것이 없으면 Ruby 1.8.7에서 몇 가지 선택을 할 수 있습니다.

  1. 반복 (더 일치가 없다면 gsub! 반환 nil) 만들어 더 대체가 없을 때까지 1.8.7를 들어

    loop { break unless string.gsub!(/([^\\])"/, '\1\"') }

  2. , 당신은 보이는 숨김 주장이 없습니다. 하지만, 문자열을 반대로 변경 사항을 만들기 위해 예견에게 주장을 사용할 수 있습니다 다음, 그것을 다시 역 :

    string = string.reverse.gsub(/"(?!\\)/, '"\\').reverse