모든 일은 한 줄의 제보에서 시작됐다. #엄격 #근엄 #진지


원래 그런지는 모르겠지만 불편한 점이 한 가지 있는데, 정규식으로 한글 문자열을 바꿀 때 문제가 있더군요.
예를 들어 "가나다aBc1"라는 문자가 있을 때…


메모장2에서는(아마도 Scintilla를 사용하는 대부분의 편집기는 모두…) 한글에 대해 정규식이 정상적으로 동작하지 않는다.

즉, 아래와 같이 입력한 상태에서…



찾을 문자열을 ([^\dA-Za-z])로 하고 바꿀 문자열에 \1-을 입력하여 모두 바꾸기를 실행하면…

ANSI 모드에선 아래와 같은 충격적인(?) 결과가 나온다.



유니코드 모드에서는 조금 다르지면 역시 충격적인 것은 마찬가지[…]



이는 근본적으로 Scintilla의 정규식 엔진 및 본 블로그 배포버전에서 사용되는 DEELX 정규식 엔진문제가 있기 때문이다.

그런데, 대략 아래와 같은 상황이 배경에 깔려있어 직접 삽질하는 것 외엔 답이 없다[…]


1. Scintilla의 정규식 엔진은 다국어 지원이 고려되어있지 않음


2. 문의 결과 제작자도 이 사실을 알고 있지만, 이 문제를 수정할 계획은 없음


3. 현재 배포판에 적용한 정규식 엔진은 DEELX 엔진


4. 이 엔진도 같은 문제가 있으며, 홈페이지에서는 1.2가 공개, 적용 버전은 1.3의 변형판[…][각주:1]라 물어보기도 복잡함


5. 즉, 현재 적용한 내용을 기반으로 직접 삽질해야 함


본질적인 문제의 해결 방향은 간단(?)하다.


1. 정규식 검사시 무조건 1바이트 단위로 이동하는 것을 1글자 단위로 수정


2. 이를 위해서 1바이트가 1글자가 아닌 경우를 별도로 식별


3. 식별된 경우 이동은 바이트 단위가 아니라 글자 단위로 진행


그런데, 문제가 하나 있다… 메모장2는 편집 단위에서 ANSI 등의 MBCS 모드와 유니코드/UTF-8 등을 모두 지원한다.

즉, 2번을 식별하려면 좀 거창한(?) 코드[각주:2]를 만들어야 한다는 뜻이다. 젠장…


We will find a way. We always have.
우린 답을 찾을 것이다. 늘 그랬듯이.


하지만, 찾아보니 다행스럽게도 이미 MovePositionOutsideChar()라는 이름으로 Scintilla에서 구현해뒀다.

그리고, 이를 적절한 위치에 적용하여 문제를 해결했다.


이제 ANSI 모드에서도 아래와 같이 정상적으로 처리되고…



UTF-8 모드에서도 정상적으로 처리된다…



이로써 근 1달 간의 삽질[…]을 마치고 답을 찾고야 말았다[…]



덧. 이 수정은 유니코드를 제대로 지원한다는 것을 의미하지 않는다.

    즉, \uD83D 같은 형식은 여전히 적용되지 않음



  1. PR을 올린 RaPeHoff 님이 직접 수정하신 것 같기는 한데, 이 PR이 반영되지 않았음[…] [본문으로]
  2. 현재 코드페이지를 확인한 뒤 거기에 맞게 '글자의 내부에 있는지'를 확인해야 함 [본문으로]
신고
  1. 영언 2017.09.11 03:00 신고

    정말 감사합니다.
    저번에 말씀드린 정규식 문제는 r995 버전을 받아서 해결된 것을 확인했습니다.
    생각보다 복잡한 문제가 얽혀 있었군요.

    이제 파일에 암호도 걸 수 있으니 중요 정보를 저장할 수 있겠군요.

    • 참고로, 한글 적용 기능을 추가하면서 없던 버그가 추가되어 최종 배포판에는 다시 이 기능을 뺐습니다.
      수정 후에 다시 포함하겠습니다[...]

+ Recent posts