深入理解内容匹配
前端精髓
共 3810字,需浏览 8分钟
· 2021-09-11
之前在了解 Vue 模板编译的原理过程中,是通过正则去匹配然后生成一个树结构的对象,代码因为太多造成不太好理解,今天重新改写了一下,通过括号匹配来模仿标签匹配的过程。
实现匹配 [111[2]111] 输出一个树结构的对象。
let endTag = /^\]/
let startTag = /^\[/
function parseHTML (html) {
var index = 0;
while (html) {
// console.log(html)
var textEnd1 = html.indexOf('[')
var textEnd2 = html.indexOf(']')
if (textEnd1 === 0 || textEnd2 === 0) {
var endTagMatch = html.match(endTag);
if (endTagMatch) {
// 结束位置
var curIndex = index;
advance(endTagMatch[0].length);
continue
}
var startTagMatch = html.match(startTag);
if (startTagMatch) {
// 开始位置
var curIndex = index;
advance(startTagMatch[0].length);
continue
}
}
// 文本位置
var text = (void 0);
if (textEnd1 >= 0) {
// 优先匹配左括号[1[1]]
text = html.substring(0, textEnd1);
}
if (textEnd1 < 0 && textEnd2 >= 0) {
// 左括号没有再匹配右括号
text = html.substring(0, textEnd2);
}
if (textEnd1 < 0 && textEnd2 < 0) {
// 左右括号都没有
text = html;
}
if (text) {
advance(text.length);
}
}
function advance(n) {
index += n;
html = html.substring(n);
}
}
执行代码,我们可以清楚的理解是挨个字符进行匹配,每次匹配到内容都使原字符减少,直到把所有的字符都匹配完成。
let html = '[111[2]111]'
parseHTML(html)
// 匹配过程
[111] ]
111[2]111]
[111] ]
2]111]
]111]
111]
]
根据整个匹配的过程,我们就可以生成树结构的对象,利用栈后进先出的特性可以处理依赖关系。
let html = '[111[2]111]'
let endTag = /^\]/
let startTag = /^\[/
var currentParent;
var stack = [];
var root;
function end(tag, start) {
var element = stack[stack.length - 1];
// pop stack 出栈
stack.length -= 1;
currentParent = stack[stack.length - 1];
closeElement(element);
}
function start(tag, attrs, unary, start, end) {
var element = createASTElement(currentParent);
if (!root) {
root = element;
}
currentParent = element;
// push stack 入栈
stack.push(element);
}
function chars(text, start, end) {
var children = currentParent.children;
if (text) {
var child;
child = {
type: 'text',
text: text
};
if (child) {
children.push(child);
}
}
}
function closeElement (element) {
if (currentParent) {
currentParent.children.push(element);
element.parent = currentParent;
}
}
function parseHTML (html) {
var index = 0;
while (html) {
console.log(html)
var textEnd1 = html.indexOf('[')
var textEnd2 = html.indexOf(']')
if (textEnd1 === 0 || textEnd2 === 0) {
var endTagMatch = html.match(endTag);
if (endTagMatch) {
var curIndex = index;
advance(endTagMatch[0].length);
end()
continue
}
var startTagMatch = html.match(startTag);
if (startTagMatch) {
var curIndex = index;
advance(startTagMatch[0].length);
start()
continue
}
}
var text = (void 0);
if (textEnd1 >= 0) {
// 优先匹配左括号[1[1]]
text = html.substring(0, textEnd1);
}
if (textEnd1 < 0 && textEnd2 >= 0) {
// 左括号没有再匹配右括号
text = html.substring(0, textEnd2);
}
if (textEnd1 < 0 && textEnd2 < 0) {
// 左右括号都没有
text = html;
}
if (text) {
advance(text.length);
}
chars(text)
}
function advance(n) {
index += n;
html = html.substring(n);
}
}
parseHTML(html)
function createASTElement (parent) {
return {
type: 'tag',
parent: parent,
children: []
}
}
console.log(root)
最后生成的结构如下:
{
"type":"tag",
"children":[
{
"type":"text",
"text":"111"
},
{
"type":"tag",
"children":[
{
"type":"text",
"text":"2"
}
]
},
{
"type":"text",
"text":"111"
}
]
}
评论
python读取多个excel表多个sheet后映射匹配再分组计算、纵向拼接
大家好,我是飞奔的蜗牛ing。一、前言前几天在一个客户给到一单数据处理的 问题,需求是这样的:1.表“aa2020”中2020年数据需要按季度分成四个表。(1-3月、4-6月、7-9月、10-12月)2.表“2020年一季度”代表2020年一季度客户所对应的管理档位,需要把表中的档位导入附表“aa2
IT共享之家
0
深入理解Camera 二 (相机架构概览)
和你一起终身学习,这里是程序员Android经典好文推荐,通过阅读本文,您将收获以下知识点:相机架构概览Android系统利用分层思想,将各层的接口定义与实现分离开来,以接口作为各层的脉络连接整体框架,将具体实现的主导权交由各自有具体实现需求的平台厂商或者Android 开发者,这样既做到把控全局,
程序员Android
10
深入理解Camera 三 (相机应用层)
和你一起终身学习,这里是程序员Android经典好文推荐,通过阅读本文,您将收获以下知识点:一、概览二、Camera Api v2三、Camera Framework四、Camera App Demo相机应用层一、概览相机应用处于整个框架的上层,在现实生活中,为了满足各式各样的应用场景,会加入很多业
程序员Android
10
LWN:Elisp里另一种模式匹配条件执行方式!
关注了就能看到更多这么棒的文章哦~An alternate pattern-matching conditional for ElispBy Jake EdgeMarch 1, 2024Gemini translationhttps://lwn.net/Articles/961682/我们在十一月份看到过 的关于在 Emacs...
Linux News搬运工
0
深入解析Spring Boot中RedisTemplate的序列化机制与JSON存储
在昨天的文章(SpringBoot 响应 json 数据的后端源码处理流程)中,有人留言说,让我唠叨唠叨 SpringBoot 中 redis 的序列化器。redis 缓存序列化,用的人很多,但是很少有人关注底层的细节,基于此,我就在写一个姊妹...
业余草
0
第2章:控制流程:深入探究 Python 条件语句
点击上方“ Python学习开发 ”,选择“ 加为星标 ” 第一时间关注Python技术干货! Python 3 是一种动态、解释型的高级编程语言,以其简洁明了的语法和强大的功能而广受欢迎。上一节介绍 Python 3 中的标准输入和输出,...
Python学习开发
0
不引入ES,使用MySQL实现分词模糊匹配
来源:juejin.cn/post/7340574992256466953推荐:https://t.zsxq.com/18Mq6lus4业务场景概述目标是实现一个公司的申请审批流程,整个业务流程涉及到两种角色,分别为商务角色与管理员角色。整个流程如下图所示:核心...
业余草
0
深入理解 K3s 镜像重写:从配置到实际应用
什么是 K3s 镜像重写? 在 K3s 镜像仓库配置中,每个 Mirror 都可以配备一组 Rewrites。这些 Rewrites 能够根据正则表达式对镜像标签进行调整,解决了当镜像仓库中的组织或项目结构与上游不一致的情况。 例如,以下...
边缘计算k3s社区
0