원래는 MV엔진 번역하기에 있던 거였죠..?

굳이 MV엔진이 아니더라도 다 쓸 수 있는 거였는데, 붙여 놓을 필요가 없다고 생각했습니다.

원래도 분리하고 싶었지만 내용이 많기도 하고, 그 생각을 가졌었던 때가 정규식 중반부 작성이 끝났을 때였습니다.

그렇지만 이제라도 분리했으니 마음이 편합니다.

식당에 올려도 되지만 기왕 쓰는 거 여기에 남겨두고 싶었습니다.


이제 막 이사를 시작해서, 여기에 얽힌 링크가 많을텐데, 다 이곳으로 옮길 예정입니다.

가독성도 괜찮게 카테고리를 한번 싹 바꿀 겁니다.


질문을 남겨주시면 최대한 답변해 보도록 하겠습니다.


앞으로 수정할 것 = 전체적으로 재검토 + 작성 예정 글 마무리





업데이트가 11월 이후로 멈춰져 있는 이유


https://arca.live/b/kazetranslateif/91034505?p=1


요약 : 현생 문제로 무기한 보류


적는 이유 : 마냥 기다리시는 분들을 위해서 작성합니다






24년   3월   31일

문단의 간격을 가독성이 좋도록 띄움

(아카라이브의 고질병)


쓸모 없는 것들은 부분 삭제가 이루어짐

(정규식 메커니즘)





17,000 자가 넘어가지만, 배우고 싶으시다면 정독하는 걸 추천 드립니다.




찾기 어려우시면 Ctrl + F 기능을 활용하세요. 

검색에 용이하도록 같은 단어는 거의 쓰이지 않았습니다.







요런 식으로









전체적인 차례




● Rengex

Rengex 차례

→ Rengex 란

→ 사용법 (수정 중)

→ .repla  ♤ (작성 예정)

→ .match  


● 정규식

정규식 차례

→ Regex 101 와 Rengex 에 대한 설명

→ 기초적인 설명

→ Step 1

→ Step 2

→ Step 3

→ Step 3 (간편 수정) (심화)

→ 한 걸음 더

→ 응용

→ { EX }


● 정규식의 그 밖에

정규식의 그 밖에 차례

→ ^ 를 쓸 때 주의사항

→ 특수 문자

→  아나모네 주석 없애기 (작성 예정)
→  ruby 텍스트 삭제 (작성 예정)












● Rengex




Rengex   ( github 링크 )

Rengex를 이용한 번역 (이지트렌스 번역 기반) (링크)


정규식을 이용한 작업이기에 얄팍한 컴퓨터 언어 관련 지식이 필요합니다.

하지만 자료를 찾아보기 힘들고, 찾는다 해도 이해하기 어렵기에


초심자를 위해서 정규식 카테고리를 만들어 놓았으니 그걸 참고해 주세요.


MV에서 제일 많이 쓰는 건


(?<=D_TEXT[ ])(?<oswtext>.+$)|

(?<=ShowInfo[ ])(?<ddtext>.+$)


이 2개 입니다.





√ Rengex 차례




→ Rengex 란
→ 사용법
→ .repla

→ .match 





Rengex 란




어떤 유저가 Regex 라는 정규식으로 대사를 뽑아낼 수 있도록 만든 툴을 가리킵니다.


 " C# 을 기반으로 설계되어 있습니다 "


따라서 Rengex 를 사용하기 위해서는 

Rengex의 사용법 + 기본적인 정규식 사용법 + Rengex 만의 정규식 사용법

을 알아야 합니다.


거창하게 말했지만 별거 없습니다. 툴을 만드신 분에게 감사를 표합시다.





사용법




──── 전제 ────


모든 설명은

https://github.com/nanikit/Rengex#matchtxt

└ 이 Rengex github 링크의 적혀져 있는 설명을 바탕으로 합니다.

└ 그대로 옮겨 적은 것도 있다는 얘기


전처리 후처리는 지금 설명하지 않습니다. ( 나중에 글에서 패치 될 내용입니다 )


① 전처리 후처리를 제외하고, 처음에 받아 들이기 어렵지 않은 내용으로만 구성하였습니다.


② Rengex 의 정규식 과 관련된 부분은 { ●정규식 } 부분에서 설명합니다. 

여기서는 Rengex 그 자체의 사용법 만을 다룹니다.


③ 내리면서 읽다 보면 자연스럽게 알 수 있도록 하였습니다.



정확한 내용을 알고 싶으시다면 어차피 다운로드도 해야 하니 

github 에서 설명을 읽어 보면 되겠습니다.







다운로드 하기



https://github.com/nanikit/Rengex#matchtxt

해당 링크로 들어가면



이렇게 나옵니다.


여기서 



노란색 영역을 클릭하면



이렇게 나올 겁니다.


그리고



이렇게 노란색 영역을 다운 받으면



얘 하나 나오는데, 잘 다운 받으신 겁니다.






처음 실행


실행하면



이렇게 뜹니다.

버튼들이 많아 보이지만 간단합니다.


더불어서



같은 경로에 이런 폴더도 하나 생겼을 겁니다.

( PS : 이거랑 같은 경로에 txt 문서 하나 생성 되었을 건데. 그건 툴 제작자 분의 패치 노트나 읽을 거리가 들어 있습니다 )






구조 ─ 1


아마 처음 실행을 하면



이렇게만 뜰 겁니다.

.match 에 정규식을 넣고

.repla 에 전처리 후처리 식을 넣으면 되는데

정규식은 밑에서 설명 드릴 것이고, 전처리 후처리는 나중에 한다고 했지만

.match 는 중요하기에 따로 설명하는 파트가 있습니다.






.match  에 정규식 넣기


( 이 카테고리의 .match 파트 설명을 읽기 )



이 부분






번역 하고 싶은 파일 넣기



노란색 영역이 사용자가 번역하고 싶은 파일이나 폴더를 드래그 하는 영역입니다.

다른 곳은 모르겠지만, 저는 이렇게 사용하고 있습니다.


여기에 넣는 건 

1개 ~ 여러 개의 파일 (갯수 제한 모름) (2천 여개 까지는 해봄)

혹은

1개 ~ 여러 개의 폴더 (갯수 제한 모름)

가 가능합니다.






구조 ─ 2


위에서 번역 파일을 넣으면




많은 폴더가 생깁니다.



1_original

번역 원본 파일이 들어있습니다.

설명에 따르면 복사한 파일입니다.



2_meta

<영어로 된 그룹> 의 영어로 된 그룹으로 나뉩니다.

이렇게 말이죠.


딱히 건드릴 필요 없습니다.



3_source

정규식으로 뽑아낸 일본어 원문이 있습니다.



4_target

정규식으로 뽑아낸 일본어 원문을 Ehnd 를 이용해서 번역했던 것들이 있습니다.



번역된 텍스트가 아예 없는 경우에는 크기가 0KB 가 됩니다.

이걸 이용해서, 특정 파일을 빼버리는 것도 가능합니다.



5_result

위의 것들을 병합하여 결과물이 도출되는 곳입니다.




작성자가 주로 쓰는 방법에는


5_result 에서 그대로 파일을 쓰는 것


오류가 있을 때 3_source 에서 비교해서 수정


4_target 에서 수정하여 5_result 로 뽑아내는 방법이 있습니다.

(이게 수정한 파일 내보내기에서 쓰는 것)






수정한 파일 내보내기



노란색 영역의 버튼을 클릭하면 4.target 에서 수정된 파일이 5.match 로 저장됩니다.





.repla  ♤


(작성 예정)



.match  




초기 상태



처음에는 이렇게 밖에 없어야 합니다. (나머지는 직접 지우세요)


이제 밑줄에 사용자가 짠 정규식을 넣는 방식입니다.



이렇게

( 중간에 #이 들어가 있는 건 혹시 몰라서 집어 넣은 것 )

( 위의 설명을 읽어보면 알겠지만 #은 주석 처리 됨 )








rengex 사용 팁 ( 링크 )


알려주셔서


  Rengex 에는 폴더도 집어넣을 수 있습니다.

집어넣은 폴더 안에 있는 것들을 다 번역해 버립니다.

하지만 일부 MV엔진 이나 다른엔진 처럼 JSON  &  js  &  tjs  &  KS  등등, 파일 종류에는 여러가지가 있습니다.

대사 같은 경우에는 주로 JSON 파일이나 KS 파일들에 들어있고, 나머지 파일들은 변수 + 선택지 입니다.

따라서 각 파일마다 따로 짜서 활용을 해야 하지만 그럴 필요 없이

원래는 .match.txt 라는 파일로 되어 있는 것을

.js.match.txt 라고 이름을 고쳐서 js 파일에만 쓰이는 명령어를 따로 짤 수 있다는 것입니다.

이건 MV엔진 같은, 어떤 규칙이 정해져 있는 파일의 경우 정말 쓸만합니다.

한번에 짜고 돌려 버리면 되기 때문이죠.












● 정규식





위의 글을 보셨던 분은 알겠지만 Rengex 를 사용하기 위해서는 정규식 작업이 필수적입니다.

직접 알아보는 건 시간이 많이 들기에, 번역을 하는 데 필요한 표현을 설명하고자 합니다.



 이건 그냥 프로그램의 P 자도 모르는 허접이 쓰는 글이기에 피드백 받습니다.

몇 번 써보지도 않았어요. 솔직히 도움을 받은 게 큽니다.


최대한 자세히 설명한다고 했는데, 이해하기 쉬웠으면 좋겠네요.


 만약 "어... 너무 어렵네. 나 이거 안 할래 ~" 라고 해도 상관 없습니다. 

하지만 모든 걸 번역하려고 한다면 시간이 많이 소모가 될 것입니다.

정규식 쓰면 그냥 넣어 버리면 되니까 간단하지만... 정규식을 짜는 연습이 필요합니다.

굳이 다른 예제들로 연습하지 말고 게임 하나 가져다 놓고 해보세요. 금방 늡니다. 

(제가 1달 하고 조금 더 걸려서 웬만한 건 짤 수 있을 정도이니 여러분들도 할 수 있습니다 !)


 



MV엔진이 아니더라도 다른 곳에서 쓸 수 있습니다. 

( 모두 정규식과 번역하는 방식을 포함한 글, 해당 글은 해당 링크의 맨 아래에 링크되어 있음 )

(전부 18금 게임)


ex  :  아이돌 매니저 R18 모드 (한글 패치)  

(주의 점 : 영어는 번역이 안되니 워드 파일로 변환할 텐데. 강제로 확장자 바꿔서 하지 말고(줄 수가 달라짐), 복붙 해야 함)


ex  :  Kirikiri 엔진 :  LOVELY×C∧TION2 + Append (한글 패치)


ex  :  티라노(공룡) 엔진 : 남은 1년의 사랑 (한글 패치)





√ 정규식 차




→ Regex 101 와 Rengex 에 대한 설명

→ 기초적인 설명

→ Step 1

 Step 2

 Step 3

→ Step 3 (간편 수정) (심화)

→ 한 걸음 더

 응용

 { EX }





Regex 101 와 Rengex 에 대한 설명




1. 모든 정규식은 \s  \n 같은 줄바꿈 기호 를 쓰지 않는 이상 문장으로서 인식한다.






2. 이 사진에서는 gmix 가 뜨는, 혹은 그 장소에 녹색으로 적혀있는 문자를 클릭하여 저 4개를 넣어야지 Rengex 에서 작동한다. (gmix 든 gxmi 든 설정이 되는 것이 중요하다)

(아니면 식을 인식하지 못한다. 물론 되는 경우도 존재)

( C# 의 경우 처음 그대로로 진행하더라도 지금까지 딱히 문제되는 건 없었으므로 빗금 처리 )







3. C# 기반으로 짜보자


링크 (클릭)

알려 주셔서 감사합니다  


(위의 링크 설명 정리 + 그룹 이름)



왜 C# 으로 짜는 지는 설명하지 않겠습니다. ( Rengex 에 설명 있음 )


문제는  C# 같은 경우에 링크에 나와있는 것처럼 " 이 특수 처리 되어 "" 으로 해야 " 가 1개가 있는 것으로 인식한다.

따라서 " 가 있는 경우에는 "" 으로 나타내지만, 

Rengex 에서는 "로 인식하는 것이 아닌 "" 로 인식한다. 따라서 바꿔줘야 한다.



 또 다른 얘기를 하자면  C# 에서는 분명 문제가 없는 구성이었는데  PCRE (PHP < 7.3) 에서 다르다며 빨간색으로 되는 부분이 발생한다.

""가 아닌 다른 경우에는 전혀 문제될 것이 없으니 그냥 """ 으로만 바꿔주고 진행하면 된다. 

(예를 들면 .*? 같은 것이 C# 에서는 잘 되었는데  PCRE (PHP < 7.3) 로 넘어가니 빨간색으로 뜨는 경우)



 그룹에 관해서는 < > 안에 들어갈 이름이 같아도 상관없는지 아니면 달라야만 하는지 정확히 모르겠다.

작성자는 < > 안에 들어가는 이름을 원래부터 다르게 입력을 했었기 때문에 해당 논제?에 대해서는 오류가 나는가? 

라고 묻는다면 바로 위의 문장으로 답변을 대신하겠다.


 그룹 이름을 같게 만들어도 딱히 상관이 있을 것 같지는 않지만, 그렇다고 해도 그룹의 이름이 같으면 이 그룹이 어떤 것을 번역하는지 확인하는 작업이 상당히 피곤하기에 개인적으로는 그룹의 이름을 다 다르게 하는 것을 추천한다.



여기서 말하는 C# 이나 PCRE (PHP < 7.3) 가 뭐냐면


이걸 얘기하는 것이다.


C# 으로 제대로 테스트를 한 후 " 만 제대로 바꿔준다면, 따로  PCRE (PHP < 7.3) 로 테스트 할 필요 없다고 작성자는 생각한다.






4. 세이브 + 업데이트



지금은 비활성화 되어 있지만 저기서 Save 를 누르면 저장이 완료 되고

Updata 를 누르면 지금 저장되어 있는 거에서 업데이트 한다는 얘기이다. 

업데이트를 하면 맨 뒤에 \1 이었던 게 \2 로 바뀐다.

(잘못된 방법으로 사용될 요지가 높지만. 교육용이니까 그런 짓을 할 사람은 없다고 생각할게.... 진심)






5. C 나 F 나 CC 는 < > 로 그룹을 묶을 때 쓰면 안된다.


https://arca.live/b/handtranslator/88093277?p=2  ◀ 자세한 건 이쪽에서.


아마도  CF 의 소문자인 cf 는 가능할 것으로 보이지만 작성자는 저 이후로 절대로 CF 를 쓰지 않는다.

오류 예시 : <TextC>

요즘에 작성자가 쓰는 것들의 예시 : <Dex1>


(정보의 출처는 저 질문 글이지만

실제로는 https://github.com/nanikit/Rengex#matchtxt  Rengex 링크에도 쓰여져 있었다)






6. 공백을 입력할 때는 \x20 을 쓰자.


 개인적으로 느낀거지만 일반적인 공백을 정규식에 그대로 써버리면 왠지 모르게 불안정한 느낌이 있었다.

실제x로는 먹기는 먹지만. 요즘에는 \x20 을 선호하는 편이다.

 \x20? 으로 공백이 1개 or 0개가 있을 수도 있다는 것도 표현이 가능하니 더욱더 저 표현을 의지하게 된다.

공백이 여러 개인 경우는 \s 로 나타내거나 \x20? 을 쓴다. 

가끔은 [공백] 도 쓰는데, 위의 것이 안정감 있다. ex : \x20?{1,4} 처럼 쓸 수도 있음.






7. 여기서 다뤄지는 정규식 문자의 종류


\d , \s , \S , \n , ( ) , [ ] , { } , | ,  .+ ,  .* , \x20? , \x20 , \

( ^ ) , ? , (?!-) , (?<=) (?=) , (?!) , ( ^ ) , (.)





기초적인 설명 (동작 방식)



정규식에는 여러가지 표현이 있다.


일단 설명하기에 앞서서 공백을 표현할 마땅한 표현이 없기 때문에 공백 이라고 표현하겠다. (스페이스 공백)






★ 먼저 알고 가야 할 정규식 단어들


( )

정확한 건 작성자도 잘 모른다. 설명을 어떻게 해야 될지 모르겠다. 

(그냥 글을 보면서 얘가 이런 거구나 라는 식으로 받아 들면 될 것 같음 )


<>

다른 곳에서는 모르겠지만 여기서는 Group 으로 정의한다.


[ ]

안에 들어있는 문자를 포함하되 그 중 1개만 있어도 된다. 

ex : [1234] 면 1이 들어있든 2가 들어있든 3이 들어있든 4가 들어있든 상관 X 

(만약에 123[45] 면 123를 포함하고 다음에 오는 숫자가 4나 5여야 한다)


?

이 앞에 쓰여져 있는 그룹 or 단어가 0개 혹은 1 개와 일치한다. 

(있을 수도 있고.. 없을 수도 있고.. 를 프로그램에서는 이렇게)


.

는 뒤에 한 글자를 인식해라 라는 의미이다. (마침표). 

다른 의미로도 쓰일 수 있지만 이것만 단독으로 쓰일 때는 이렇게 정의한다.


.+ 

는 뒤에 문자가 뭐가 오던지 1개 이상 포함하라는 의미이다. 

당연히 그룹이 있거나 특정 단어에서 시작하면 그 이후로만 포함한다.


|

(\ 키를 Shift를 누르고 입력하면 나오는 문자)(키보드 마다 다를 수 있음) 는 or 를 의미한다. 

(한국어로는 "또는" 이라고 한다)


나머지

사용자가 설정한 단어들이다. 

(따로 프로그램에 대한 기호라기 보다는 그 부분의 문장을 토대로 검색하도록 하는 거니까 따로 신경은 안써도 된다)






 설명은 작성자가 이해한 대로만 적은 거고, 오류가 있을 수도 있다. 

자세한 건 다른 사이트나 블로그 등에 많이 적혀져 있으니까 그걸 참고하면 된다.




이제 시작



MV에서 제일 많이 쓰며, 동시에 그나마 쉬운 식이 


D_TEXT[ ](?<oswtext>.+)    

▲  얘로 설명할 거다.  ▲






이 식에서 하고 싶은 것 :

D_TEXT 공백 부분을 제외한 부분을 번역하고 싶다.



https://regex101.com/r/i7Xn0F/1 (관련 페이지)


글자로만 설명하면 어떻게 되는지 감이 안 잡히니까 하나 하나 뜯어보자.





(1). D_TEXT 는 말 그대로의 의미로 문자를 인식한다.




(2). D_TEXT 와 더불어서 공백 이 선택된다.




(3). (2)번에서의 부분보다 뒤를 oswtext 로 묶는다. 

(지금은 괄호 안에는 식이 없으니 묶이지 않는 모습. 분홍색 점이 세로로 나열 된 부분)




(4). (2)번에서의 부분보다 뒤에 한 글자를 oswtext 로 묶는다.



(5). (2)번에서의 부분보다 뒤에 오는 1개 이상인 부분을 oswtext 로 묶는다. (문자 밑 공백 포함)


위에 것을 한 문장으로 하면 D_TEXT와  공백 을  인식하고 난 다음에 나타나는 모든 문장을 oswtext 로 묶는다.

라는 설명이 된다.



이 과정에서 Showinfo로 글자만 바꾼 것이 밑에 있는


ShowInfo[ ](?<ddtext>.+)


이 식이다.



여기서 조금 더 쓸모가 있는 걸로 나아가자.





Step 1
\s  ,  { }



★ 먼저 알고 가야 할 정규식 단어들


\s

줄 바꿈과 공백 과 Tap 을 읽는다. 

당연히 \를 붙이지 않으면 일반적인 s 라는 문자로 기능한다. 

하지만 설명의 간소화를 위해 특정 부분만 써 놓겠다.


{}

{1,3}   이면 1번 이상 3번 이하,  {1}  이면 1번 이상






이 식에서 하고 싶은 것

1: 이라는 글씨부터 번역하는 게 아니라 저 Name 옆에 특정 글자를 기준으로 줄을 바꿔서 번역하고 싶다.



https://regex101.com/r/YwcHau/1 (관련 페이지)



説明文言\s{1,3}1:'(?<aext>.+?)[']


식은 이렇다






위에서 \s{1,3} 부분을 설명하면



1번 OK



2번 OK



3번 OK



4번 X


( 이 과정에서는 1번 보다 못한 0번을 어떻게 할 수 없어서 여기까지만 설명했는데 

Step 2 에서 0번 ~ 4번 이상 까지 설명 되어 있다)


식을 해석하자면  説明文言 이 문장과 \s로 줄바꿈을 읽되 패턴이 1번 이상 3번 이하가 반복이 되며 1: 를 읽고 다음에 나타나는 ' 를 제외한 부분부터 시작하되 어떠한 경우도 상관 없으나 맨 마지막에는 ' 가 들어가 있어야 한다.


라고 해석해 볼 수 있다.


그룹의 이름이 다른 것은 위에 Regex101 의 3번째 에서 설명을 해 놓았으니 참고.



이 정도면 아주 간단한 건 짤 수 있다. 하지만 조금만 틀어져도 막힌다. 그러므로 더 나아가 보자.





Step 2
\x20?  ,  \x20  ,  \d





★ 먼저 알고 가야 할 정규식 단어들


\x20

볼 수 있는 문자와 공백


\d

모든 숫자. 당연히 \를 붙이지 않으면 일반적인 d 라는 문자로서 기능한다.


\(정규식 문자)

이건 말 그대로의 의미인데 주로 \?[ 등과 같은 경우는 정규식에서 역할이 존재하지만, 

그 부분을 문자처럼 쓸 수 있게 끔 바꿔주는 역할을 한다.






이 식에서 하고 싶은 것 :

code 408 indent 부분과 parameters 부분을 검색하고, 바로 밑에 있는 문장을 번역하고 싶다.



이런 걸 하고 싶은데


"code":\x20?408,\s{1,3}.+"indent":\x20?\d{1,3},\s{1,3}.+"parameters":\x20

\[\s{1,3}.+?"(?<text>.+?)"


식이 이 모양으로 좀.... 많다.


괜찮다. 여기서 설명하고자 하는 의미는 간단하니까.



식이 길기 때문에 나눠서 설명하겠다






☆ 앞 부분

("code":\x20?408,\s{1,3}.+"indent":\x20?\d{1,3},) 


"code":408, 을 하고 \s 로 줄바꿈과 공백을 포함하는데 그게 1번 이상 3번 이하가 존재하며

이걸 인식한 후 .+ 로 뒤에 있는 1개 이상의 문자들을 포함 시키다가

"indent":에서 정지 + 포함 하고 \d 로 모든 숫자를 포함 하되, 한 번 에서 많게는 세 번 사이에 문자가 존재하며, 쉼표가 표시되기 전 까지만 포함하며 쉼표를 포함한다.


2번째 문장에서 \d 로 부터 시작되는 곳을 간단하게 하면





123, (동작 함)



12, (동작 함)



1, (동작 함)



1234, (동작 안 함)




, (동작 안 함)


이렇게 된다.




☆ 뒷 부분


\s{1,3}.+"parameters":\x20

\[\s{1,3}.+?"(?<text>.+?)"


를 설명하면


\s 로 줄바꿈과 공백을 포함하는데 그게 1번 이상 3번 이하가 존재하고

.+로 1개 이상의 모든 문자를 포함하다가 "parameters": 에서 정지 + 포함하고, 볼 수 있는 문자와 공백을 지나서 \[[ 를 문자열로 나타내는 기호가 아닌 일반 [ 을 먹을 수 있는 것으로 바꾸어 준 후 \s 로  줄바꿈 + 공백을 인식하되 그 것이 1번 이상 3번 이하가 존재하고

.+?로 1개 이상 있을 수도 있고 없을 수도 있는 문자를 다 포함하는데 에서 멈춘다.




☆ text Group


Group 에서  <text> Group 으로 설정 할 거고 뒷 부분을 다 <text> Group 으로 설정한다.




 끝 문자


Group 으로 다 묶지만 끝에는 문자 " 가 있어야 하며, Group 에는 묶이지 않는다.




●  위의 식에서 수정 ver


"code":\x20?408,\s{1,3}.+"indent":\x20?\d{1,3},\s{1,3}.+"parameters":\x20

\[\s{1,3}.+?"[ ](?<text>.+?)"


https://regex101.com/r/Vm4pQE/1  (관련 페이지)


좀 더 길어지기는 했지만, 좀 보완을 한 거고 몇 개 추가되지도 않았으니까 직접 확인해 보시라





Step 3
(?!-)  ,  \S




★ 먼저 알고 가야 할 정규식 단어들


(?!-) 

왼쪽에 적혀져 있는 부분을 먹지 말아주세요 하는 것들이고, 같은 그룹에서도 작동한다.


\S  

모든 문자를 말한다. (공백, 줄바꿈, Tap 키 제외)






Plugins.js


이 식에서 하고 싶은 것 :

title 부분의 문자와 description 의 문자와 \n 부분의 문자를 이어서 번역하고, 

\hint 의 문자와 \n 부분의 문자를 이어서 번역하고 싶다.



PCRE 동작 확인





C# 동작 확인



https://regex101.com/r/KYECys/1  (관련 페이지)


"title\\\\\\":\\\\\\"(?<atext>.+?)[\\"]|

"description\\\\\\":\\\\\\"\\\\\\\\\\\\\\"(?<btext>\S{1,1000})\\\\\\\\\\\\\\"\\\\\\",\\\\\\"icon(?!-)|

"hint\\\\\\":\\\\\\"\\\\\\\\\\\\\\"(?<ctext>\S{1,1000})\\\\\\\\\\\\\\"\\\\\\",\\\\\\"isSecret(?!-)



식이.... 음.....  


일단  \  가 많이 보인다. (무식하긴 하다)


식이 좀 길지만. 사실 간단하다.





☆ title 부분


"title"\\\":"\\\" 부분까지 인식하고 저 부분의 뒤부터 atext 라는 Group으로 묶되 그 모든 문자는 1개 이상 1000개 이하가 있으며 \" 가 나오면 그 전까지만 인식한다

로 "or" , "또는" 이라는 의미로 사용되게 끔 만든다.




☆  description 부분


"description\\\":\\\"\\\\\\\"
부분을 인식하고 그 뒤부터 btext 라는 Group으로 묶되 모든 문자는 1개 이상 1000개 이하가 있으며
\\\\\\\\n\\\\\\\"\\\",\\\"icon

부분을 인식하는 곳 까지 멈추고 (?!-) 이 있기에 윗 부분을 btext Group 에서 제외한다 .

로 "or" , "또는" 이라는 의미로 사용되게 끔 만든다.




☆  hint 부분

(방식이 description과 같으므로 생략



어렵지는 않고 Regex 101 링크도 달아 놓았으니 저 부분을 지우면 어떤 일이 일어나는지 알아봐도 좋을 것 같다.




Step 3 (간편 수정) (심화)
(?=)  ,  (.*)  ,   | 의 쓰임새



★ 먼저 알고 가야 할 정규식 단어들


(?=)  

이 안에 들어가 있는 문자의 앞 부분까지만 인식하도록 한다. (match 에 선택되지 않는 것이 장점)


(.*) 

앞에 있는 문자가 뭐든 0개 이상 먹는다.


앞에서 설명했다시피 "or" 라는 기능을 가지며, 그건 새로운 식을 쓸 때만이 아닌 그룹 안에 쓰든 어디든 상관 없다.






Step 3 에서 보면 알겠지만 식이 길다....

물론 프로그램을 짜는 것은 아니기에 저래도 상관없지 않을까 생각하지만. 조금 더 줄어든 방식을 소개하고자 한다.




https://regex101.com/r/uk8Ml8/1 (관련 페이지)


"title\S{1,8}"(?<Atext>.*?)(?=\S{1,9}description)|"(description|hint)\S{1,17}(?<Btext>.*?)(?=\S{1,16}(?="icon|"isSecret))



이건 오히려 저 Step2 보다 식이 쉬울지도 모르겠다.






식 설명


"title 라는 곳에서 시작해 문자들이 1개 이상 8개 이하가 있으며 그 끝에는 "가 있는 곳부터 Atext Group을 묶다가 description 과 그 앞 부분에 문자가 1개 이상 9개 이하인 부분까지만 묶고, ?= 의 괄호로 묶인 부분은 선택되지 않는다


로 "or" , "또는" 이라는 의미로 사용되게끔 만든다.


description 또는 hint 에서 시작해 문자들이 1개 이상 17개 이하가 있고, 그 후로 Btexet 로 Group으로 묶되 "icon"isSecret 의 앞에 있는 1이상 16개 이하의 문자를 제외하며. 이 "icon"isSecret 의 앞에 있는1이상 16개 이하의 문자는 선택되지 않는다






선택되지 않을 때의 장점


선택이 되지 않는 것이 중요한데... 중복 선택이 되면 다시 | 로 옆에 이어서 식을 짤 때 그 부분을 선택할 수 없다.

따라서 Regex 에서 ( 파란색 = match )로도 나타내지 않는 것이 중요하다.






★ 살짝의 개편


https://regex101.com/r/lvoFLT/2

(?<=title).+?".+?"(?<Dex1>.*?)(?=\\)|(description|hint).+?".*?".+?"(?<Dex2>.*?)\\|(?<=\\n)(?<Dex3>.*?)(?=\\)


 구조를 알고 있다면 굳이 저 \S{1,16} 같은 것을 쓰지 않더라도 이렇게 만들 수도 있다. (갯수를 세기 귀찮을 때)

안정성을 생각한다면 \S 식, 아니라면 개편한 식


 개편한 방식은 23년 10월 24일 작성하는 지금 제일 선호하는데.

번역할 때 내가 원하는 부분만 < > 안에 묶이도록 하는 것이다.

이러면 따로 오류가 거의 안 생기기 때문이다. (제작사가 뭔 짓을 해 놓지 않은 이상)




한 걸음 더
(?<=)  ,  ( ^ )  ,  \n



이제 진짜로 어느 정도는 다 배웠다. 그래도 문자를 1개만 아는 거랑 여러 개 아는 것은 다르다.

이건 MV는 아니지만 티라노 정규식을 가지고 와봤다.






★ 먼저 알고 가야 할 정규식 단어들


(?<=) 는 괄호 안에 해당되어있는 문자가 끝나는 부분부터 인식이라는 의미이다. (?=) 의 반대

( ^ ) 는 무조건 문장의 시작 부분을 가리킨다. (중간도 안되고 끝도 안되고 무조건 문장의 시작 부분)

( \n ) 은 줄바꿈을 의미한다. ( \s줄바꿈 , Tap , 공백 을 의미했다면 여기서는 줄 바꿈만)






이 식에서 하고 싶은 것


티라노 엔진 에서는 # 앞에 붙은 것이 이름이다. 그리고 대사가 나오는데 

[r] 은 줄바꿈, [pex] 는 대사를 끝내는 명령어로서 작용한다.

그리고 #(이름) 바로 밑줄에 [r] 과 [pex] 가 있으므로, 

만약 #(이름) 하고 밑에 [r] 과 [pex] 가 나타나지 않으면 번역하지 않는다.

[r] 이 여러개가 있는 경우가 있으므로, [r] 밑에 [pex] 가 있던 [r] 밑에 [r] 이 있던 그 부분들을 번역한다.




https://regex101.com/r/0c9AxH/1 (링크에서 확인) (C#으로 되어 있음)


^\#(?<nameAnonName>.*?)\n(?<textA>.*?)(?<=(\[r\]|\[pex\]))|\n(?<textB>.*?)(?<=\[r\]|\[pex\])|^\#(?<nameBnonName>.*?)\n(?<Outtext>.*)






식 설명


^로 처음만 선택되게 만들어 주고 그 다음은 #이 오면 그 후에는 nameAnonName 이라는 그룹으로 묶는데 줄바꿈이 나타나는 부분까지 묶는다. 그리고 바로 textA 라는 그룹으로 묶되 끝에는 를 써서 [r] 이나 [pex] 가 와야 하며, 그 [r] 이나 [pex] 는 그룹에서 선택되지 않는다.

로 "or" , "또는" 이라는 의미로 사용되게끔 만든다.




줄바꿈 후 textB 가 되는 데 끝에는 를 써서 [r] 이나 [pex] 가 있어야 하며, 그 [r] 이나 [pex] 는 그룹에서 선택되지 않는다.

로 "or" , "또는" 이라는 의미로 사용되게끔 만든다.




^로 처음만 선택되게 만들어 주고 그 다음은 #이 와야 하며 

그 후에 nameBnonName 이라는 그룹으로 묶어주고

 \n 으로 줄바꿈, Tap,  공백이 오고(여기에서는 줄바꿈이 우선시 되기에 그것만)

 Outtext 라는 그룹으로 문장이 끝날 때 까지 묶는다.



응용
(?!)



★ 먼저 알고 가야 할 정규식 단어들


로 "or" , "또는" 이라는 의미로 사용되게끔 만든다.

(?!) 로 괄호 안에 있는 것들은 match에도 포함되지 않게 한다. (은근히 많이 쓰임)






이 식에서 하고 싶은 것 : 

- 티라노 엔진 에서는 # 앞에 붙은 것이 이름이다. 

그리고 대사가 나오는데 [r] 은 줄바꿈, [pex] 는 대사를 끝내는 명령어로서 작용한다.

끝에 [r] 과 [pex] 가 붙은 경우는 거의 대사밖에 없지만 처음에 명령어로 시작되는 [ 부분은 선택되지 않도록 한다.

플레이어의 이름을 정하는 부분은 처음에 [ 가 들어있지만 

특정 명령어인 [emb 같은 것으로 되어있고 그 이후에 name"] 로 이름 명령어가 끝나고 

나머지는 [r] 이나 [pex] 로 마무리가 되기에 명령어 부분은 건드리지 않으면서 대사만 번역되도록 한다.




^\#(?<nameA>.*)|^(?!\[)(?<textA>.*?)(?=(\[emb|\[r\]|\[pex\]))

|^(\[emb).*?(name"\])(?<textB>.*?)(\[emb|\[r\]|\[pex\])

|(?<=name"\])(?<textD>.*?)(?=(\[r\]|\[pex\]))



https://regex101.com/r/2bfS49/1 (링크 참조)






★ 자잘한 설명을 없애서 간소화



○  (nameA 그룹)

처음 시작 부분이 #가 끝나는 부분부터 끝까지 nameA 라는 그룹으로 묶는다.




○  (textA 그룹)

처음 시작 부분이 [ 면 안되지만 [emb 같은 플레이어 명령어가 있으므로 그 부분은 선택하는 기능만 담당하고,[emb 이나 [r] 이나 [pex] 부분이 있으면 거기까지만 textA로 묶이되, [r] 이나 [pex] 부분은 match로 선택되지 아니하며, 일반적인 그룹으로만 묶인다.




○  (textB 그룹)

처음에 [emb 로 시작하고 끝에는 name"] 으로 끝나는 명령어는 선택이 되고, [emb 같은 플레이어 명령어가 존재하면 그 부분은 선택하는 기능만 담당하고, [emb 이나 [r] 이나 [pex] 부분이 있으면 거기까지만  textB 로 묶이되, [r] 이나 [pex] 부분은 match로 선택되지 아니하며, 일반적인 그룹으로만 묶인다.




○  (textD 그룹)

name"] 라는 문구로 시작하고 중간에 대사들은 textD 로 묶이지만, 끝에는 [r] 이나 [pex] 가 있어야 하고, [r] 이나 [pex] 부분은 match로 선택되지 아니하며, 일반적인 그룹으로만 묶인다.




{ 정규식 매커니즘 }



내용적으로 맞지 않는 부분이 많아서, 빼버렸습니다.
시간이 나면 써 보는 것으로 할게요.


{ EX }




보충 설명 : 난이도는 알아보기 쉬운 순서대로 정했다. 복잡할 수록 식이 길어지고 특이해진다.

(처음부터 복잡한 걸 보지 않는 것을 추천한다. 하다 보면 자연스럽게 늘게 된다.)


얻어가야 할 점 : 보다 보면 특정 패턴의 반복이 눈에 띌 건데, 그걸 중심으로 보면 된다. 

나머지는 각자의 상황에 맞추도록 한다. 굳이 이걸로 연습해 보지 않아도 된다. 

각자가 번역하려는.. 혹은 뽑아내려는 파일을 가지고 연습해 보면 된다.


아주 쉬움

https://regex101.com/r/lGMyXs/1

https://regex101.com/r/ZsWyLR/1


쉬움

https://regex101.com/r/dCiFbw/2


조금의 응용

https://regex101.com/r/QI28yF/3

https://regex101.com/r/dCLG7B/2


복잡

https://regex101.com/r/P0of1k/2

https://regex101.com/r/Q4kmHq/2


???

https://regex101.com/r/w2n8rg/1











● 정규식의 그 밖에




위의 것만 있어도 되지만 이건 작성자가 하면서 이 방법을 알면 조금 편하겠는데? 하는 것들을 정리해 놓은 것입니다.




√ 정규식의 그 밖에 차례




→  ^ 를 쓸 때 주의사항
→  특수 문자

→  아나모네 주석 없애기 (작성 예정)

→  ruby 텍스트 삭제 (작성 예정)





^ 를 쓸 때 주의사항




https://regex101.com/r/GGMGyR/2  (예시)


여기에서는 난 【 】  이런 걸로 묶인 걸 이름이라고 따로 묶고 싶었고 

저게 1개만 나오는 경우도 아니었기에 연속해서 하고 싶었는데


^하고 (?! 【) 를 해버리면 이제 그걸로 시작되는 문장은 못쓴다.


정확하게는 아예 처음 시작으로 걸어 버렸기에 따로 선택이 되지도 않는다. ( | 를 해도 마찬가지다 )

^같은 경우 처음 시작 부분을 선택하지만 그건 단어도 아니고 진짜로 처음 시작되는 부분이다.

(링크에서는 아마도 분홍색 점이 세로로 나열된 모습을 볼 수 있다)

따라서 작성자는 그것의 관한 식을 짤 때   를 먼저 짜서, 【 】 가 여러 개가 나오더라도 사용할 수 있게 했다.


결론 : ^를 쓸 때는 주의 깊게 쓸 것.




특수 문자




나무위키 (완성형 / 특수문자)  ◀  (링크)


전각 로마자 : 가끔 보이는 A 보다 공간을 많이 차지하는 문자

정규식 : [A-Z]


전각 숫자 (아라비아 / 로마) : 가끔 보이는 일반 숫자보다 큰 공간을 차지하는 숫자

정규식 : [0-9]











끝인사 + 이 글을 작성한 이유




이런 걸 적는 게 맞나 싶지만...
만든 이유가 있습니다.

여기에 따로 적었을 때를 말하는 게 아니라 
이 글이 처음으로 나오게 된 이유를 사담을 살짝 섞어서 얘기해 보려고 합니다.

일단 자주 도움 받았던 분에게 정규식에 대해서 많은 도움을 받았습니다.
그리고 본격적으로 정규식 표현들을 알아보기 시작했죠.
그랬더니 세상에나... MS 에서는 사용자가 어떤 작업을 하는 지 모르기 때문에 온갖 표현을 다 적어 놓았고 
(이게 맞기는 합니다)

어떤 곳에는 전화번호 + 우편번호... 라는 예제를 들며 알려주고 있었습니다.
그 분들을 폄하하는 건 아닙니다. 그 나름대로의 방향성이 있을 겁니다.

하지만 저는 그런 것과 맞지 않았습니다.
결국 여러가지 도움을 받아가며 배우고, 그걸 남에게 가르쳐보자고 다짐 했을 때
저 같은 사람이 있을 수도 있겠다는 생각이 들었습니다.
알아보려고 하는데 너무 어렵고, 난잡해서 정보를 모으기 힘든 경우를 말이죠.

검색하는 방법을 몰라도, 아무리 귀찮은 사람이라 해도
이 글을 읽으면 어느 정도 할 수 있도록 해보자
라는 목적으로 만들었습니다.

3번째 작성하는 거라 그나마 완성도가 있는 글입니다.
부족했던 점이 있다면 그건 저의 역량 문제인 것 같습니다.
어떤 사람은 이 글을 보면서 제가 전화번호를 봤었을 때랑 같은 감정을 느꼈을 수도 있겠죠.


그렇다면


저에게 피드백을 주시거나, 직접 작성하시면 됩니다.
저는 여기에서 후자에 속하겠네요.
글을 작성해 보니 많이 어렵지 않더라고요.


이 글을 읽어주신 모든 분들 께 감사드립니다.
좋은 번역 합시다.



Good Luck
with your Translation