4.1 初版Scanner (token) 只能 扫描普通字符串

const templateStr=`<h3>我今天买了一部{{thing}}手机,花了我{{money}}元,心情好{{mood}}啊</h3>`;

初步实现普通字符串的扫描和生成token

export default class Scanner {
  constructor(templateStr) {
    this.templateStr = templateStr;
    this.index = 0; //指针初始位置
    this.tail = templateStr; //一开始就是模板字符串
  }
  /**
   * @tag {string} 指定tag?和stopTag有啥关系呢
   * @returns {undefined}
   * 走过指定内容,无返回值
   */
  scan(tag) {
    //先执行scanUntil 在执行scan
    if (this.tail.indexOf(tag) !== 0) return;
    this.index += tag.length; //tag有多长 index执行后移几位
    this.tail = this.templateStr.slice(this.index);
  }

  /**
   * @stopTag{string} 扫描结束标记
   * @returns {string} 让指针进行扫描,直到遇见指定标记stopTag结束,返回结束之前扫描经过的文字
   * 双指针算法 本质
   */
  scanUntil(stopTag) {
    // `<h3>我今天买了一部{{thing}}手机,花了我{{money}}元,心情好{{mood}}啊</h3>`;
    //记录一下每次执行scanUntil方法时候index值
    const indexBackup = this.index;
    //当尾巴字符串不是以指定stopTag作为开头  说明还没有扫描到stopTag 那么继续
    while (this.tail.indexOf(stopTag) !== 0 && this.eos()) {
      this.index++;
      this.tail = this.templateStr.slice(this.index);
    }
    //返回结束之前扫描经过的文字
    return this.templateStr.slice(indexBackup, this.index);
  }
  //指针是否到头  end of string
  eos() {
    return this.index < this.templateStr.length;
  }
}

生成tokens

import Scanner from "@/my_mustache/Scanner";

export default function parseTemplate2Tokes(templateStr) {
  console.log("templateStr :", templateStr);
  let tokens = [];
  const scanner = new Scanner(templateStr);
  let word;
  //当指针没有走到头 继续
  while (scanner.eos()) {
    word = scanner.scanUntil("{{");
    if (word) tokens.push(["text", word]);
    scanner.scan("{{"); //跳过左{{
    // console.log(scanner);
    word = scanner.scanUntil("}}");
    if (word) {
      //word 就是{{}} 双大括号里面的内容
      if (word[0] === "#") tokens.push(["#", word.slice(1)]);
      else if (word[0] === "/") tokens.push(["/", word.substring(1)]);
      else tokens.push(["name", word]);
    }
    scanner.scan("}}"); //跳过左{{
  }
  return tokens;
}
原文地址:https://www.cnblogs.com/xiaoliziaaa/p/14256546.html