diff --git a/src/lexer.ts b/src/lexer.ts
index e0bc57f..6e948eb 100644
--- a/src/lexer.ts
+++ b/src/lexer.ts
@@ -9,8 +9,6 @@ const MESSAGES = {
   UNEXP_EOT: 'Unexpected end of template',
 };
 
-const BLOCK_COMMENT_REGEX = /\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g;
-const SINGLE_LINE_COMMENT_REGEX = /\/\/[^\n\r]+?(?:\*\)|[\n\r])/g;
 
 export class JsonTemplateLexer {
   private readonly codeChars: string[];
@@ -18,10 +16,7 @@ export class JsonTemplateLexer {
   private idx = 0;
   constructor(template: string) {
     this.buf = [];
-    this.codeChars = template
-      .replace(BLOCK_COMMENT_REGEX, '')
-      .replace(SINGLE_LINE_COMMENT_REGEX, '')
-      .split('');
+    this.codeChars = template.split('');
   }
 
   init() {
@@ -146,10 +141,62 @@ export class JsonTemplateLexer {
     return this.buf[steps];
   }
 
-  private advance(): Token {
-    while (JsonTemplateLexer.isWhiteSpace(this.codeChars[this.idx])) {
+  private isLineCommentStart(): boolean {
+    return this.codeChars[this.idx] === '/' && this.codeChars[this.idx + 1] === '/';
+  }
+
+  private isLineCommentEnd(): boolean {
+    return this.codeChars[this.idx] === '\n';
+  }
+
+  private isBlockCommentStart(): boolean {
+    return this.codeChars[this.idx] === '/' && this.codeChars[this.idx + 1] === '*';
+  }
+
+  private isBlockCommentEnd(): boolean {
+    return this.codeChars[this.idx] === '*' && this.codeChars[this.idx + 1] === '/';
+  }
+
+  private skipLineComment() {
+    if (!this.isLineCommentStart()) {
+      return;
+    }
+    while (!this.isLineCommentEnd()) {
       ++this.idx;
     }
+    ++this.idx;
+  }
+
+  private skipBlockComment() {
+    if (!this.isBlockCommentStart()) {
+      return;
+    }
+    while (!this.isBlockCommentEnd()) {
+      ++this.idx;
+    }
+    this.idx = this.idx + 2;
+  }
+
+  private isWhiteSpace() {
+    return ' \r\n\t'.includes(this.codeChars[this.idx]);
+  }
+
+  private skipWhitespace() {
+    while (this.isWhiteSpace()) {
+      ++this.idx;
+    }
+  }
+
+  private skipInput() {
+    while (this.isWhiteSpace() || this.isBlockCommentStart() || this.isLineCommentStart()) {
+      this.skipWhitespace();
+      this.skipLineComment();
+      this.skipBlockComment();
+    }
+  }
+
+  private advance(): Token {
+    this.skipInput();
 
     if (this.idx >= this.codeChars.length) {
       return {
@@ -229,10 +276,6 @@ export class JsonTemplateLexer {
     return '0123456789'.indexOf(ch) >= 0;
   }
 
-  private static isWhiteSpace(ch: string) {
-    return ' \r\n\t'.indexOf(ch) > -1;
-  }
-
   private static isIdStart(ch: string) {
     return ch === '$' || ch === '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
   }
diff --git a/test/scenarios/comments/data.ts b/test/scenarios/comments/data.ts
new file mode 100644
index 0000000..ec02d3b
--- /dev/null
+++ b/test/scenarios/comments/data.ts
@@ -0,0 +1,7 @@
+import { Sceanario } from '../../types';
+
+export const data: Sceanario[] = [
+  {
+    output: ["////", "/*** /// */"],
+  },
+];
diff --git a/test/scenarios/comments/template.jt b/test/scenarios/comments/template.jt
new file mode 100644
index 0000000..ed2cf85
--- /dev/null
+++ b/test/scenarios/comments/template.jt
@@ -0,0 +1,6 @@
+// line comment
+/**
+ ////////////////
+ * block comment
+ */
+["////", "/*** /// */"]
\ No newline at end of file