어린 시절을 추억해 보니, 보수가 어쩌면 처음으로 산수와 수학에 대해서 무언가 느낀 첫관문이었던 것이 기억난다. 초등학교 1학년 때였는데, 숫자를 50까지는 셀 수 있었지만, 그게 무엇이고 숫자가 무엇인지 전혀 개념이 없었다. 그러다가 속셈 학원을 다녔는데, 그 속셈 학원에서 제일 먼저 배운 것이 보수(짝궁수)였다. 선생님은 큰 성냥곽 같은 상자를 보여주면서 그것을 보수 상자라고 불렀다.

    

요렇게 생긴 상자였다



보수 상자는 가운데에 상자 높이 반 정도 되는 문턱이 있고 빨간 구슬들이 들어 있었다. 성냥곽처럼 양 옆에 뚫려 있어서 양 옆으로 상자를 꺼내볼 수 있었는데 선생님은 그 상자를 손에 잡고 마구 흔드시면서 자신은 한쪽만 열어 보고 반대쪽에 몇 개의 구슬이 있는지 알 수 있다고 말했다. 그러면서 나에게 보수상자를 주면서 흔들어 보고 한쪽을 박스 내부를 밀어서 몇 개의 구슬이 있는지 보여주라고 하셨다. 나는 열심히 흔들었고 한쪽을 열어 보니 6의 구슬이 보였다.

    

선생님 : 몇 개의 구슬이 있나요?

나 : 6가 있어요.

선생님 : 그럼 다른 쪽에는 4의 구슬이 있습니다. 확인해보세요.

나 : 반대쪽을 열어 보았고 놀랍게도 4의 구슬이 있는 것을 확인했다



몇 번을 더 해봤지만 선생님은 웃으면서 정확하게 반대쪽의 구슬의 개수를 정확하게 모두 맞추었다. 호기심과 신기함에 내 눈이 반짝반짝 빛났을 즈음에 선생님은 보수의 개념을 설명해주었다.

   

선생님 : 손가락은 몇 개가 있나요?

: 10

선생님 : 그럼 손가락을 모두 펴고 그 중에서 6만 접어 보세요. 그럼 몇 개의 손가락이 남나요?

나 : (손가락을 세어보면서) 4

선생님 : 그럼 그 4의 손가락에서 다시 10의 손가락으로 손을 모두 활짝 피려면 몇 개의 손가락을 다시 펴야 하나요?

나 : 6.

선생님 : 10의 손가락이 우리 손가락의 개수예요. 만약 1의 손가락을 핀 상태에서 다시 10개를 채우려면 다시 9의 손가락을 펴야 합니다. 반대도 마찬가지죠. 9의 손가락을 핀 상태에서 10개의 손가락을 채우려면 1의 손가락을 펴줘야 해요. 그런가요?

나 : (손가락을 꼬물거려 보면서)

선생님 : 이렇게 1의 손가락에서 10의 손가락을 채우기 위해서 필요한 수가 9지요. 1의 손가락이 10가 되고 싶어서 필요하고 보충해야할 손가락이 9니까 1의 보수는 9예요

 

선생님은 이런 과정을 숫자마다 반복했고, 그 다음은 보수 상자를 주면서 잘 생각해보라고 말씀하시고 다른 학생을 가르치러 가셨다. 나는 호기심에 보수 상자를 갖고 이쪽저쪽의 숫자를 계속 확인해보다가 그제서야 상자의 한쪽에 있는 구슬의 개수와 상대의 반대쪽에 있는 구슬의 개수가 보수 관계에 있다는 것을 깨달았다. 상자 안에는 총 10개의 구슬이 있었고 따라서 한쪽에 6의 구슬이 있으면 반대쪽에는 4의 구슬이 있을 수밖에 없는 것이다.


즉, 보수상자는 다음처럼 작동하고 있었던 것이다. 

 

그리고 이 현상이 내게는 너무 신기한 것이었다. 초등학생의 인지 수준에서 인과란 무언가 직접적인 작용이 있어야 하는데 그런 직접적인 작용 없이 한쪽이 결정되면 반대쪽도 그 개수가 결정되는 것에 경이감을 느꼈다. 그러면서도 잘 납득이 되지 않아서 계속 보수 상자를 흔들었다. 아무리 시간이 지나도 어떤 짓을 해도 그 관계가 바뀌지 않는 것을 확인하면서 처음으로 숫자라는 것이 무언가 실체적으로 다가왔다.

      

숫자를 50까지 셀 수 있었지만 그것이 무엇인지는 잘 몰랐다. 그냥 1 다음은 22 다음은 3 식으로 하다 보니 50까지 셀 수 있었지만 이 숫자라는 것이 무언가를 가리키고 어떤 관계를 가지는 것이라는 점에 대한 느낌이 전혀 없었다. 그냥 어머니가 시키는 알 수 없는 무의미한 숫자 세기에 불과했던 것이 이 보수 상자를 통해 최초로 어떤 실체감을 가지고 다가온 것이다. 아이들을 가르치시는 분이라면 이 보수 상자를 만들어 보수의 개념을 스스로 발견하게끔 유도해보는 것이 어떨까 싶다.


Anki 파일 


보수(짝궁수)에 대한 Ankl는 다음과 같이 구성했다.

첫 번째 파일은 10에서 숫자를 빼기해서 나오는 수를 계산한다.

두 번째 파일은 어떤 수를 제시하고 그 수를 10으로 만들기 위해서 어떤 수가 필요한지 묻는다.

세 번째 파일은 10을 만들기 위해서 필요한 수가 보수라는 개념을 설명하면서 각각의 수의 보수를 묻는다. 

네 번쩨 파일은 이 보수가 (19), (28), (37), (46), (55)로 서로 짝을 이루는 짝궁수라는 것을 확인한다.


보수(짝궁수)의 개념1(10에서 숫자 빼기).apkg

보수(짝궁수)의 개념2(10이 되기 위해서 필요한 수).apkg

보수(짝궁수)의 개념3.apkg

보수(짝궁수)의 개념4(짝궁수 확인).apkg







문자 클래스


문자열 관련 탐색을 할 때는 앞서 포스팅한 문자열 탐색에서와 같이 그냥 해당 문자열을 바로 탐색하는 것이 가장 간단하다. , 정방향으로 abc라는 문자열을 문서를 탐색할 때는 다음과 같이 명령 라인에 명령어를 입력하면 된다. 


/abc


그런데 abcAbc로 맨 앞의 a가 대문자이거나 소문자인 경우를 모두 같이 탐색하고 싶으면 어떻게 해야 할까?


다음처럼 검색하면 된다.


/[Aa]bc


여기에서 대괄호([ ])로 묶인 것을 문자 클래스라고 부른다. 문자 클래스는 이 대괄호 사이에 있는 문자 중 하나와 일치하면 해당 문자와 일치하는 것으로 본다. 따라서 해당 위치에 올 수 있는 여러 문자들을 문자 클래스([ ]) 내에 배치하면 다양한 문자열을 아래와 같이 간단하게 찾을 수 있게 된다.


정규표현식과 일치하는 문자열

[ab]c ac, bc

[Aa] Ab, ab

[1234]class  1class, 2class, 3class, 4class


문자 클래스([ ])하이픈(-)을 이용하여 범위를 지정할 수 있다


정규표현식과 일치하는 문자

[a-z] 알파벳 소문자

[A-Z] 알파벳 대문자

[1-9] 1에서 9까지의 숫자

[a-zA-Z0-9] 모든 알파벳과 숫자


또한, 문자 클래스([ ]) 내에 캐럿(^)을 이용하여 not의 의미를 부여할 수도 있다.

 

[^Ff]uck uck 문자열 중에서 F 워드를 제외

[^0-9] 숫자가 아닌 경우


Anki 파일


아래는 본 포스팅의 내용을 갈무리하기 위한 Anki 파일입니다. 참고하시기 바랍니다. 


정규표현식 개요


정규표현식을 공부하기에 앞서 정규표현식이란 무엇이고 왜 공부하는게 좋은지 조금 동기부여를 해볼 필요가 있다. 


정규표현식이란 무엇일까? 간단하게 정의하면 다음과 같다


정규표현식문자열의 집합을 표현하는 데 사용하는 형식 언어이다.


정규표현식문자열집합이라는 형태로 다루는 형식 언어이기 때문에, 단순히 몇몇 프로그램이나 vim에서 일시적으로 제공하는 도구가 아니다. 


형식 언어로 학문적인 틀을 갖추고 진지하게 연구되어 개발되었기 때문에 그 구현에 있어서 문법과 버전이 조금씩 다를 수는 있어도 그 본질이 크게 달라질 수는 없다. 그리고 대부분의 문법도 편의성 때문에 조금씩 다르게 적용되는 것 말고는 거의 유사한 것으로 알고 있다. 이 이야기는 정규표현식을 익혀놓으면 그것이 소프트웨어 개발이건, 텍스트 편집이건, 운영체제 운용이든 평생 유용하게 써먹을 수 있다는 이야기이다. 물론, 현재에도 정규표현식은 vim 뿐만 아니라 다양한 텍스트 에디터, Unix/Linux 계열의 애플리케이션소프트웨어 개발 등에서 폭넓게 사용되고 그 유용성을 인정받고 있다. 또한, 데이터 유효성 검사, 데이터 웹 스크랩핑, 문법 구현 등에서도 매우 유용하게 쓰이고 있다. 

 

처음 정규표현식을 접하게 되면 각종 기호와 문자가 복잡하게 얽혀있는 모습이 초보자에게 부담스럽게 다가오지만 유용하게 사용할 수준까지는 매우 쉽게 익힐 수 있고 익혀두면 정말 쓸 곳이 많고 유용하다. 다음이 사례를 보면 그 유용성을 느낄 수 있을 것이다. 

 

아래는 자바스크립트에서 전화번호를 입력받아서 그 전화번호가 올바른 형식으로 입력되었는지 확인하는 함수를 구현해본 것이다.


function phone(number) {

  if (number.length > 8 || number.length < 7) {

    return false;

  }

  var numFirst = number.substring(0, 3);

  var numSecond = number.substring(number.length - 4);

  if (isNaN(numFirst) || isNaN(numSecond)) {

    reuturn false;

  }

  if (number.length === 8) {

    return (number.charAt(3) === "-");

  }

  return true;

}


위의 함수는 꽤 간략하게 코드를 정리한 것이다. 하지만 정규표현식을 이용하면 이 코드가 다음과 같이 줄어든다.


function phone(number) {

  return number.match(/^\d{3}-?\d{4}$/);

}


내부 블록에 12줄로 작성된 함수가 마법처럼 1줄로 줄어들었다. 이처럼 정규표현식을 사용하면 문자열 관련 프로그래밍을 하거나 수만 줄의 코드에서 원하는 문구를 정확히 찾아내는 등 문자열 관련한 작업에서 압도적인 효율을 갖출 수 있게 된다.

 

Anki 파일


아래는 본 포스팅의 내용을 갈무리하기 위한 Anki 파일입니다. 참고하시기 바랍니다. 


이번 Anki는 "정규표현식문자열의 집합을 표현하는 데 사용하는 형식 언어이다." 라는 구절만 공부합니다. 


027 vim의 정규표현식(1).apkg


+ Recent posts