2013-07-31 4 views
1
-- Converts tabs to spaces 
function detab(text) 
    local tab_width = 4 
    local function rep(match) 
     local spaces = -match:len() 
     print("match:"..match) 
     while spaces<1 do spaces = spaces + tab_width end 
     print("Found "..spaces.." spaces") 
     return match .. string.rep(" ", spaces) 
    end 
    text = text:gsub("([^\n]-)\t", rep) 
    return text 
end 


str=' thisisa string' 
--thiis is a  string 

print("length: "..str:len()) 
print(detab(str)) 
print(str:gsub("\t"," ")) 

markdown.lua의 코드 조각을 사용하여 탭을 공백으로 변환합니다 (이름에서 알 수 있듯이).
내가 알아 낸 점은 문자열을 검색하여 탭을 찾아 일치하는 부분 문자열을 'rep' 함수에 전달할 때까지 문자열을 검색한다는 것입니다. 더 이상 일치가 없을 때까지이 작업을 반복합니다.
루프는 while 루프에서 특히 rep 함수가 수행하는 작업을 파악하려고합니다.
왜 루프가 1에 멈 춥니 까?
왜 카운트 업합니까?.
현저하게, 문자열의 공백 수를 계산합니다. 정확히 얼마나 수수께끼입니까?
출력을 마지막으로 gsub 대체 출력과 비교하면 차이점을 발견 할 수 있습니다.
Detab은 gsub 대체하지 않는 동안 문자 정렬을 유지 관리합니다. 그 이유는 무엇입니까?
보너스 질문. Scite에서 공백을 켜면 't' 이전의 탭이 세 번째 's' 이전 탭보다 긴 것을 알 수 있습니다. 왜 다른가요?루아에서이 detab 함수는 어떻게 작동합니까?

+0

'로컬 스페이스 = tab_width - #match % tab_width' –

답변

1

보너스 질문에 답하려면 탭 문자는 탭 스톱에 정렬됩니다. 탭 정지는 8 자입니다. 첫 번째 탭은 6 열에서 시작하므로 3 개의 공백을 채워야합니다. 두 번째 탭은 열 16에서 시작하므로 한 칸 넓이 여야합니다.

루프가 양수가되면 루프가 멈 춥니 다. 루프는 일치하는 텍스트보다 긴 공간이 충분해질 때까지 '들여 쓰기'간격으로 공백을 추가하기 때문입니다. 그런 다음 해당 수의 공백을 일치하는 텍스트와 결합하면 올바른 탭 정지 점에 채워지는 문자열이 생성됩니다.

그래서 gsub가 다른 이유입니다. gsub는 탭을 탭 정지 문자로 취급하는 것이 아니라 4 개의 공백으로 취급합니다. 따라서 두 번째 탭은 tabstop에 채워지지 않고 네 개의 공백으로 확장됩니다.

4

rep 함수를 분석 한 결과,이 현상이 나타난 것입니다. 먼저 전달 된 일치 문자열의 길이를 가져 와서 음수로 만듭니다 (예 : -1을 곱하는 것과 같이). while 루프에서는 양수가 될 때까지 공간에 계속 추가됩니다.

이 숫자 줄을 사용하여 시각화하는 것이 더 쉬울 수 있습니다

본질적으로
<--|----|-------|----|----|----|----|----|----|----|----|---> 
    -n  -spaces    -2 -1 0 1 2 n 

, 루프가 "tab_widths은"을 "오버 플로우"전에 공간에 적합 얼마나 많은 내기 위해 노력하고있다. 여기에서는 컷오프 포인트로 0에서 1 로의 전환을 사용합니다. 루프가 끝난 후 spaces은 얼마나 오버플로되어있을 것입니다.

사실 while 루프는 모듈로 알고있는 수학 연산을 모방합니다. 다시 말해서, 내부 rep 기능이 같이 쓸 수있다 :

local function rep(match) 
    local spaces = tab_width - match:len() % tab_width 

    return match .. string.rep(" ", spaces) 
end 

이 하나 무차별 4 개 공간 모든 탭 문자를 대체합니다 str:gsub("\t", " ") outter는 다르다.OTOH의 경우 detab 함수에서 탭 문자를 대체하는 공백 수는 일치하는 캡처의 길이에 따라 다릅니다.

eg. 
matching length is 1, replace tab with 3 spaces 
matching length is 2, replace tab with 2 spaces 
matching length is 3, replace tab with 1 space 
matching length is n, replace tab with tab_width - (n % tab_width) spaces 
etc. 
'루프가없는 함수``spaces` 계산 렙 (매치)의 등가 형태
+0

는 무차별 의미 되었습니까? –

+0

@ 예탄 그렇습니다. 그것은 제가 의미했던 것입니다, 감사합니다. – greatwolf

관련 문제