3D 구슬 굴리기 트랙으로 시각화한 정규식

Regex visualized as 3D marble run

regexmarblerun.com ▲ 87 댓글 35 seizethecheese

요약

정규식을 3D 구슬 굴리기 트랙으로 바꿔 매칭과 백트래킹 과정을 눈으로 보여 주는 웹 도구입니다.

Regex Marble Run에 자바스크립트 정규식(문자열 패턴을 찾는 표현식)과 시험 문자열을 넣으면 3D 장치가 그려지고 구슬이 굴러갑니다. HN에 올린 이용자에 따르면, 비전공자에게 코딩을 가르치던 동료가 정규식을 어려워하는 학생들을 위해 만들었습니다.

왜 중요한가

  • 기호뿐인 정규식 한 줄을 부품과 경로로 펼쳐, 엔진이 어떤 순서로 시도하는지 한 단계씩 따라갈 수 있습니다.
  • 치명적 백트래킹(되짚어 가는 시도가 폭증해 처리 시간이 급격히 늘어나는 현상)을 클라우드플레어 장애 보고서의 패턴 같은 실제 사례로 재현합니다.

핵심 내용

  • 글자마다 구슬이 하나씩 굴러가고, 게이트가 한 글자씩 검사해 통과하지 못한 구슬은 옆으로 떨어집니다.
  • 선택지가 생길 때마다 깃발을 꽂고, 실패하면 마지막 깃발로 돌아가는 방식으로 백트래킹을 보여 줍니다.
  • 예제 /^(a+)+$/에 a 16개와 느낌표를 넣으면 32만 7,694단계를 돌고도 일치하지 않습니다.
  • 캡처 그룹은 틀, 역참조는 거울, 전방 탐색은 옆 트랙을 다녀오는 작은 구슬로 표현합니다.
  • 안내문은 RE2·Go·Rust 같은 선형 시간 엔진에서는 같은 패턴도 문자열 길이에 비례해 끝난다고 설명합니다.

HN 반응

  • 정규식이 어려운 건 개념이 아니라 기호뿐인 한 줄 문법 탓이라는 지적에, 상세 모드(x 플래그)로 줄을 나누고 주석을 달면 된다는 반론이 나왔습니다.
  • 핵심 문법은 몇 개뿐이라는 의견에, 역참조(앞에서 잡은 문자를 다시 찾는 기능)는 최악의 경우 매칭 시간을 지수적으로 늘린다는 반론이 이어졌습니다.

댓글

20개 표시 · 전체 35개
  1. seizethecheese HN

    제 동료는 예전에 비개발자들에게 코딩을 가르쳤습니다. 수강생들은 늘 정규식을 가장 어려워했습니다.

    솔직히 말해 정규식은 개발자에게도 이해하기 어려울 수 있습니다. (적어도 저는 어렵습니다.)

    그래서 동료가 누구든 임의의 정규식 명령을 이해할 수 있도록 이걸 만들었습니다.

    AI 사용 공개: 이 프로젝트는 로컬 코딩 에이전트 아레나 시스템인 Agent Duel( https://github.com/bottomless/agent-duel )로 만들었습니다. 홍보 공개: 저희 회사가 Agent Duel을 만들고 있습니다. 이 시스템을 테스트하고 버그를 찾으려고 그 안에서 취미 프로젝트들을 만들고 있습니다. 그래도 HN 분들이 흥미로워하실 것 같아 올렸습니다.

  2. crazygringo HN

    정규식은 개념적으로는 엄청나게 이해하기 쉬워요.

    그런데 문법적으로는 사탄이 직접 설계한 물건이에요.

    대부분의 프로그래밍 언어는 "for", "let", "return"처럼 의미가 바로 와닿는 명령어를 쓰고, "+"나 "="처럼 이미 아는 기호를 주로 쓰잖아요. 줄바꿈과 들여쓰기로 구조도 잡고요. 여러 명령을 여러 줄에 나눠 쓰고, 주석도 달 수 있고, 다 되죠.

    그런데 정규식은 전부 구두점뿐인 데다 기호마다 자기들끼리만 통하는 뜻이 있고, 그걸 한 줄에 몽땅 욱여넣어요. 구조도 없고 주석도 없고, 매일 쓰지 않으면 기호가 뭘 하는지 기억할 수가 없어요. 정규식을 문자열로 쓸 때 겪는 이스케이프 악몽은 말할 것도 없고요. 정규식 안의 기호를 이스케이프하는 것 위에 또 얹어서요.

    정말이지 이제는 평범한 파이썬 코드나 HTML처럼 생긴 정규식 대체재가 나올 때가 됐다고 봐요. 그래서 이런 걸:

      ^(\+\d{1,3}-?)?\d{3}-\d{3}-\d{4}$
    

    이런 식으로 쓰게 되는 거죠.

      <start>
        <optional>  # Optional country code
          "+"
          <digit>[1-3]
          "-"
        </optional>
        <digit>[3]  # Area code
        "-"
        <digit>[3]
        "-"
        <digit>[4]
      <end>
    

    똑같은 거예요. 그런데 하나는 정규식을 배운 적 없는 사람에게 전혀 알아볼 수 없는 암호고, 다른 하나는 어떻게 동작하는지 꽤 쉽게 짐작할 수 있죠...

  3. kbenson HN

    원하시는 건 Raku(perl6)의 그래머와 비슷한 것입니다. 정규식을 넘어서려고 Raku가 개발한 매칭 기능의 확장이죠.

        grammar IniFile {
            token key   { \w+ }
            token value { <-[\n;]>+ }
            token pair  { <key> \h* '=' \h* <value> \n+ }
            token TOP   { <pair>+ }
        }
    
    my $text = "user = alice\nrole = admin\n";
        my $match = IniFile.parse($text);
    
    if $match {
            say "Parsed successfully!";
        }
    

    다른 언어에도 비슷한 것을 구현하거나 이 개념을 이식한 라이브러리가 여럿 있으니, 관심이 있으시면 찾아보실 수 있을 겁니다. 아니면 요즘 같은 시대에는 VC(와 사회 상당 부분)가 AI로 원하는 언어용 라이브러리를 꽤 빨리 만드는 데 보조금을 대 줄 수도 있겠죠.

    그런 걸 찾으시는 게 아니라 위에 보여 주신 예시에 더 가까운 것을 원하신다면, 특정 언어에서는 그렇게 할 방법이 흔히 있습니다. Perl에서는 정규식 안에 정규식 변수를 쓸 수 있어서 쉽습니다. my $digit = qr/(? :0-9)/;처럼 대입해 두고 말씀하신 대로 정규식 안에서 쓰면 됩니다(공백 무시도 Perl은 이미 플래그로 지원합니다). 그뿐 아니라 Perl 정규식은 DEFINE 블록에서 정규식 안에 재사용할 조각을 정의할 수도 있으니, 다른 정규식 엔진에도 이런 기능이 있을지 모릅니다.

  4. lizmat HN

    파이썬을 쓰신다면 운이 좋을 수도 있습니다. https://andrewshitov.com/2026/10/03/using-raku-in-python/ 에 파이썬에서 Raku 그래머와 액션을 쓰는 방법이 구체적으로 나와 있습니다.

  5. wongarsu HN

    가독성을 원하시면 이렇게 쓰면 됩니다.

        ^(?P<country_code>\+[0-9]{1,3}-?)?[0-9]{3}-[0-9]{3}-[0-9]{4}$
    

    대부분의 정규식 엔진에는 상세 모드(보통 x 플래그)도 있어서 이것도 유효한 정규식입니다.

      ^
      (   
          \+
          [0-9]{1,3}
          -?
      )?   # optional country code
      [0-9]{3}
      -
      [0-9]{3}
      -
      [0-9]{4}
      $
    

    다들 정규식을 읽기 어렵게 쓰는 이유가 정규식의 평판 때문에 읽기 좋게 써 봐야 소용없다고 느껴서인지, 아니면 재치 있는 한 줄짜리가 되는 것이 정규식의 핵심 매력이라서인지 잘 모르겠습니다.

  6. ryangittins HN

    실무에서는 사소하지 않은 정규식마다 단위 테스트를 넣어 두면 큰 도움이 됩니다. 어떤 문자열이 매치되어야 하는지, 그리고 어쩌면 더 중요하게는 어떤 문자열이 매치되면 안 되는지 보여 줄 수 있습니다. 캡처 그룹의 내용을 테스트하는 것도 마찬가지입니다.

    한 줄짜리 정규식에 단위 테스트를 통째로 만드는 게 우스워 보일 수 있지만, 그 한 줄이 정말 빽빽할 수 있습니다. 정규식 없이 문자열을 파싱하는 함수를 썼다면, 그 함수는 단위 테스트가 필요할 만큼 복잡했을 테니까요.

    정규식을 손볼 때 회귀가 생기는 것도 큰 위험인데, 단위 테스트가 이를 줄여 줍니다.

  7. Syzygies HN

    아메리카스컵과 포뮬러 원 경주는 설계 단계에서 승부가 갈립니다. 우리는 드라이버를 칭찬하지만, 성공을 만드는 것은 엔지니어링입니다.

    수십억 달러 규모의 IPO 가치가 걸려 있고, 피험자에게 애니메이션으로 이해를 전달하는 경쟁을 한다면 이 디자인은 바로 탈락일 겁니다. 이 모델은 지나치게 사실적이어서, 인지 대역폭 대부분을 "우와, 진짜 누가 나무로 만든 것 같네!" 하는 반응을 이끌어 내는 데 낭비하고, 정작 공이나 논리를 구현하는 기계 부품은 눈을 찌푸리고 찾아봐야 합니다. 로고 디자인에는 특별한 천재성이 필요한데, 여기에도 그것을 적용해야 합니다. 대신 이것이 만화 애니메이션이었다면, 그러니까 어느 날 월트 디즈니가 스튜디오 커피에 약을 타서 애니메이터들이 뭘 해내는지 보려 했다면, 우리는 인지 대역폭을 더 잘 써서 보는 사람과 아이콘 언어를 확립하는 시각화를 얻었을 겁니다.

    주판은 이 발상의 상징과도 같습니다. 악기처럼, 주판을 손에 들지 않고도 다루는 모습을 상상할 수 있고, 충분히 연습한 일부 가게 주인들은 주판을 서랍에 넣어 두고도 계산할 수 있었습니다. 구슬은 공처럼 물리적 현실을 다루는 우리 뇌의 능력을 활용하는데, 주판 디자인이 더 간결해질수록 셈이라는 개념은 더 생생해졌습니다. 만들고 쓰기가 쉬워졌을 뿐 아니라, 우리 정신에 심는 "사고 벌레(thought worm)"로서도 더 효과적이 되었습니다.

    우리가 외계인과 접촉했는데, 그들의 박물관에 정규식용 주판이 있다고 해 봅시다. 그건 어떻게 생겼을까요?

    이걸 제대로 해내는 것은 중요합니다. 머지않아 AI가 대화 턴마다 실시간으로 생성한 픽사 수준의 3D 애니메이션으로 우리와 소통할 것이기 때문입니다. 많은 사람이 아직 AI와의 소통을 "문자 메시지" 프롬프트를 주고받는 것으로 생각하지만, 저는 수학 연구에서 이미 대화 한 번에 삽화가 들어간 PDF 슬라이드 덱을 AI의 답변으로 받고 있습니다. 요청하기만 하면 됩니다. AI 소통의 형태는 우리의 상상력에 의해서만 제한됩니다.

    파인만 다이어그램 같은 드문 예외를 빼면, 과학적 소통은 여전히 "전신" 형태에 갇혀 있습니다. 한때 실물 종이 위에 있던 텍스트 줄을 따라 수학 기호를 읽는 방식 말입니다. 앞으로의 세대가 시각적 기호 추론에 적응하면, AI가 우리와 소통하는 데 쓰는 애니메이션은 재현적인 것에서 추상 예술로 진화할 것이고, 기호 정보를 우리 정신에 쏟아붓는 "더 굵은 파이프"가 될 것입니다. AI는 우리 정신을 가장 잘 해킹하는 "사고 벌레"를 찾아내 우리를 더 똑똑하게 만들 겁니다.

    이런 미래를 상상하신다면 정규식 뷰어가 어떤 모습일지 보고 싶습니다.

  8. atoav HN

    저는 대체로 독학으로 배운 사람이고, 필요할 때마다 그때그때 정규식을 조금씩 익혔는데, 사람들이 왜 그렇게 어려워하는지 늘 의아했습니다.

    제 생각에 문제는 전통적인 교재 상당수가 정규식의 복잡함(그리고 인상적인 가능성)부터 시작한다는 점입니다. 정규식을 배우는 가장 좋은 방법은 아마 단순한 텍스트 매칭의 확장으로 생각하는 것일 겁니다.

    정규식을 완전히 아는 것은 사실 복잡합니다. 하지만 앞으로 필요할 필터링·검색·치환의 90%를 해낼 만큼만 아는 것은 그리 복잡하지 않습니다.

  9. ogogmad HN

    저도 독학했습니다. 핵심 수량자 다섯 개를 빼면

      .
      |
      ?
      *
      +
    

    정규식에는 캡처 그룹

      ()
    

    과 핵심 수량자 "?", "*", "+"의 게으른(lazy) 변형, 편하게도 이렇게 불리는 것들뿐입니다.

      ??
      *?
      +?
    

    나머지는 전부 축약 표기입니다.

    그래서 처음부터 전부 보여 주지 말라는 제안은 일리가 있다고 생각하지만, 전체가 정말 그렇게 복잡한지는 의문입니다.

  10. ryangittins HN

    나머지는 전부 축약 표기입니다.

    정말 엄밀하게 따지자면 ., ?, +도 축약 표기입니다. 정규 표현식의 형식적 정의는 일부러 아주 최소한으로 되어 있습니다.

    .은 그냥 (a|b|c|...)입니다. 모든 리터럴 문자의 목록이죠.

    x?는 그냥 (x|)입니다. "x 또는 빈 문자열"이라는 뜻입니다.

    x+는 그냥 xx*입니다. "x 다음에 x가 0번 이상"이라는 뜻입니다.

    특정 정규식 엔진이 실제로 이렇게 구현했는지는 구현 세부 사항이지만, 형식적으로는 문법적 설탕이 아닌 연산이 아주 적습니다.

  11. StilesCrisis HN

    정규식에는 이보다 훨씬 많은 기능이 있습니다. 예를 들어 역참조(backreference)가 있죠. 그 부분집합만으로도 위험한 짓을 할 만큼은 쉽게 배울 수 있다는 데는 동의하지만, 그게 정규식이 제공하는 전부는 아닙니다.

  12. ogogmad HN

    정규식 안의 역참조(부분 문자열이 반복되는 곳을 찾는 방법)는 논란이 아주 큰 기능이라, 일부 정규식 엔진은 의도적으로 빼고 대부분은 마지못해 지원합니다. 역참조를 지원하면 골치 아픈 문제가 줄줄이 따라옵니다. 대부분의 정규식 엔진은 역참조를 만나는 순간 느리고 최적화가 형편없는 알고리즘으로 되돌아갑니다.

    또 사람들이 역참조와 캡처 그룹을 혼동하지 않는 것이 중요합니다. 조금 비슷해 보이지만 캡처 그룹은 사실 괜찮습니다.

    사실 역참조는 너무나 발등을 찍기 쉬운 기능이라, 저는 이를 정규식의 기능으로 보지 않습니다. 그것은 PCRE의 기능이고, 어쩌면 PCRE를 구분 짓는 핵심 기능이기도 합니다. 모든 정규식이 PCRE이긴 해도 모든 PCRE가 정규식인 것은 아닙니다. 일관되게 성능이 나오는 PCRE 구현은 아예 불가능합니다.

  13. teiferer HN

    "정규식"이 실제로 무엇을 뜻하는지는 수백 가지 변종이 있습니다. 기본은 대개 같지만 확장 기능은 다릅니다.

    그 토대는 결정적·비결정적 유한 오토마타(DFA와 NFA)를 다루는 이론 전산학에 있습니다. 저는 정규식을 가르칠 때 DFA를 쓰는 것이 가장 쉽다고 느꼈습니다. 동그라미와 화살표만 그리면 되니까요. 정규식 표기는 그냥 다른 표기법일 뿐입니다. 피아노를 칠 줄 알면 다른 악기를 배울 때 머릿속으로 늘 피아노를 기준 삼을 수 있어서 훨씬 쉬운 것과 비슷합니다.

    역참조는 사실 "논란"이 있는 게 아니라, 정규 언어(유한 오토마타가 인식하는 언어)로 옮길 수 없는 확장일 뿐입니다. 즉 정규식을 "비정규"로 만들기 때문에 일종의 편법에 가깝습니다. 이를 지원하려는 정규식 엔진은 근본적으로 다른 접근이 필요하고, 그래서 일부 엔진은 지원하지 않으며 원리상 앞으로도 지원할 수 없습니다.

  14. ogogmad HN

    논란이 되는 이유는, 역참조를 지원하면 최악의 경우 매칭 시간이 O(2^n)으로 늘어나 위험한 반면, 지원하지 않으면 최악의 경우에도 O(n)으로 유지할 수 있기 때문입니다. 게다가 사용자는 그 위험을 모를 수 있습니다.

    또 NFA와 DFA만 언급하면 더 깊은 이유가 없는 것처럼 보여서 오해의 소지가 있다고 생각합니다. 더 깊은 이유는 이렇습니다.

      정규식(또는 NFA, 또는 DFA)은 상수 공간에서 검사할 수 있는 문자열의 성질을 정확히 분류한다.
    

    그런 문자열 성질은 또한 O(n) 시간에, 왼쪽에서 오른쪽으로 한 번 훑는 것만으로 검사할 수 있다는 것이 밝혀져 있습니다.

    역참조로 돌아가면, 이를 지원하면 상수 공간은 달성할 수 없게 됩니다. 선형 시간도 달성할 수 없는데, 매칭이 NP-완전이 되기 때문입니다.

    그리고 실제로 DFA를 쓰는 정규식 구현은 없습니다. NFA는 쓰지만 DFA는 아닙니다. NFA의 요점은 상수 공간과 선형 시간으로 실행하기 쉬우면서 연결과 클레이니 스타도 구현하기 쉽다는 점입니다. DFA 같은 다른 대부분의 상수 공간 오토마타로 연결과 클레이니 스타를 구현하는 것은 훨씬 어려워 보이는데, 사람들이 NFA를 발명할 수밖에 없었던 것이 바로 그 때문입니다.

  15. teiferer HN

    사실 우리는 같은 얘기를 하고 있는 것 같은데, 표현 방식이 정반대이고 결론도 정반대로 나오는 게 재미있네요. :)

    잘난 척하자는 게 아니라 오히려 그 반대입니다. 암호 같은 정규식 문법 대신 동그라미와 화살표를 머릿속 모델로 쓰는 편이 직관적입니다. 둘의 의미는 같습니다. 유한 오토마타를 시각적으로 표현하면 의미에 더 쉽게 다가갈 수 있는데, 이 구슬 굴리기 그림과 다르지 않습니다.

    반면 "상수 공간", "O(n) 매칭", NP-완전성 같은 얘기를 논의에 끌어들이는 것은 형식적으로는 모두 맞는 말이고(저도 형식적 정확성의 열렬한 팬입니다), 일반인 입장에서는 바로 거기서부터 아는 체하는 얘기가 되고, 실용적으로 어떻게 돌아가는지만 알고 싶은 사람들이 떨어져 나가는 지점이기도 합니다.

    그래서 저는 쉬운 동그라미와 화살표 직관으로 시작하고, 사람들이 더 알고 싶어 할 때만 이론적 배경으로 넘어가라(즉 잘난 척하라)고 말하는 겁니다.

    (역참조는 동그라미와 화살표로 표현할 수 없는데, 이것이 역참조가 왜 특별한지를 보여 줍니다.)

  16. nick__m HN

    겉핥기만 하고 계시네요! 긍정·부정 전방탐색과 후방탐색(lookahead, lookbehind), 룩어라운드, 역참조, 재귀, 인라인 엔진 플래그 설정, 그리고 제가 잊어버린 다른 것들도 빠뜨리셨습니다. PCRE2 호환 정규식은 잠재적으로 괴물 같은 복잡한 물건입니다.

  17. monster_truck HN

    이거 꽤 만족스럽네요. 소리가 있으면 좋겠어요. 공을 따라가는 극적인 팔로우 캠도 있으면 좋을 것 같고요.

  18. hollow-moe HN

    클라우드플레어 대규모 장애 났을 때 그 정규식이 뭐였죠?

  19. fwlr HN

    입력 텍스트 상자가 301자로 제한되어 있는 것 같습니다.

  20. Sarkie HN

    이제 문제가 세 개가 됐네요.

Hacker News에서 보기 ↗