00:00
这节课呢,我们就来手写啊,咱们这个ast的一个实现。首先呢,我们肯定需要去便利啊,肯定是需要便利它,所以这个时候啊,并且还是要利用站的思想去便利它啊,那我们肯定首先第一步要准备指针。好,然后第二步呢,要先不准备占先便利它,所以while index小于呃,小于这个template string的length减一。好,直到指针便利到最后一位啊,那我这个时候呢,呃,当然这个时候肯定是死循环,因为index咱们说过它是指针是没变的。对吧,所以我们现在要让index能加加。好,这个时候呢,它就不至于死循环了啊。OK,然后我这个时候就可以输出,嗯。输出template string。
01:01
中的第因第项。好,刷新。哎,当index小于它的Les啊,然后我这个时候就输出他string d,呃,他string Les减一刷新,哎,他这个时候就能输出了。啊,没问题。大家发现了吗?对吧,那这个时候大家可能会发现一个比较恐怖的一个事情啊,就是这个空格。啊,空格会严重的干扰我们。大家发现了吗?对吧,什么意思呢?就相当于你这里是吧,它是会有一些空格的,然后标签的这里和这里也是有一些空格的。啊,那这些空格的处理的话呢,实际上我们在马touch那个时候,咱们大家其实。讲解过。啊,就是关于空格是怎么处理的啊,但是呢,咱们在这个时候就先不用去管这个空格,我们先去把这个标签的首尾空格去掉。
02:03
诶,咱们一定要保证这个标签前后是没有空格的,至于这个之间的空格,我们一会再说,他可能会被当做一个空文本处理。啊,这是很正常的,然后我们一会再去说这个空文本是怎么样给它去掉,就这个空文本其实是没有必要的啊,一会我们再去说这点。好,那所以说现在的话呢,我们就能够发现他这个东西就能做出来啊,那我们这个时候就便利他的时候,他就需要去识别他当前你便利的这个人是不是一个开始标间。啊,所以我现在就开始就是识别遍历到的这个字符啊,是不是一个开始标签,所以这个时候我们就需要用正则表达式去来测试,那正则表达式的话,实际上在这里呢,就是说我当前这个字符呢,它是用什么开始的,对,它是用这个。这个符号。啊开始的,然后呢,它里面呢,就是A到Z。
03:02
啊,这里是A到Z,诶咱们一律用小写字母,然后也不能用短横啊,因为自定义组件可以用短横,但是我们现在抽象语法数呢,就先不用自定义组件啊,组件它跟抽象语法数实际上是没多大关系的,因为它是上一层的。嗯,抽象语法数合到这一层的抽象语法数当中。所以我们在这里呢,就是命名它为小写的A到Z加,然后它有一个封闭的一个符号是这样子的。啊,然后这样子的一个检测,如果能检测到这位就是template string的话,哎,它是以这玩意开始的,那这个时候呢,我们就可以log。啊,检测到开始标记。好,然后我可以把这个开始标记呢,我可以输出出来。那这个开始标记是什么?就是tag。啊,Tag就等于什么呢?就等于我们用这个正则。是不是这块就可以补货。
04:02
哎,补货当然可以用麦吃方法。好,放括号一。这个我们在之前的储备案例当中呢,我们其实都已经。学习过了。那这个时候我们的这个指针移动咱们这个标签的长度啊,标签的长度加二,为什么要加二呢。对,因为我们大于号小于号也占两类。对吧,哎也占两位。啊,这样子的。所以这个时候呢,我们就需要让这个index加,等于咱们这个tag的N加二就可以,然后else的情况下呢,我们再找index加加。好刷新,哎,我们看一下这块有什么错误。好,他说的是这个正则,他现在是报错的。
05:01
这个正则现在果然是有错对吧,这个补货现在是补货错位置了啊。好,刷新这回就对了。啊,他就检测到开始标记第五了,然后检测到开始标记第五,他为什么老检测到开始标记第五,第五第五。大家发现了吗?老检测到开始标记第五,那就说明呃它有毛病了,我们看看为啥啊,Tag的Les加2INDEX移动。它加二刷新,诶你看它老检测到D5。啊,老检测到第五,那这是为什么呢?是哦,因为我们不是template string,对,是不是应该让我们的那个剩余部分对吧,剩余部分,所以说我们现在是剩余部分啊,我们把这个剩余部分给挖到外头去。这个也是咱们在一开始咱们的,呃。这个算法储备当中。有的内容对吧,哎,所以就是rest,就等于time string的sub index,我们给它放进去这样子的啊,剩余部分,所以这块要检测剩余部分。
06:06
而不是总检测原创啊,如果总检测原创的话呢。实际上,呃,原创是不会改变的。所以是剩余部分。哎,这样子的OK,这样的话刷新你就会发现div u l和D5对吧,哎,就都能检测出来了。啊,我们来对着看一下,这是呃,Div啊,UL。对吧,哎,然后呃,Div,但这个H3是不是没有检测出来,发现了吗?这个H3是没有检测出来呢,这个力检测到了三个,这个div检测到了两个,没问题。啊,这div检测到两个啊,这个div先删了吧,省省事啊,那这个H3现在是有毛病的,咱们来看看为什么哦,因为H3是不是中间还有数字啊,对吧,所以说这个咱们现在就是呃,A到Z前头肯定是A到Z。啊,A到Z的话呢,是一位或多位,然后后面是有数字,那就是呃,一到六。
07:05
哎,那如果是H,那就是一到六对吧?啊这样写啊。这样写,因为数字肯定是在最后的H1234嘛,就这是要是H啊,然后刷新这回就应该A,但是这块还是报错了。恩,它这个数字。这个数字在这里是有错吗?在这里写一到零到九呢。哦,因为你这里补货没补货,对对吧,这里要。啊,这里是一到六,H3是一到六啊,这里这个test的也要对吧,这回就对了,H3就对了,那这个数字可能有可能没有,所以我们打一个问号。啊,因为这个数字是可能有可能没有的啊,我们就打一个问号。对吧,哎,就行了。哎,这样,所以这些标记呢,都能检测到。啊,完全没有问题对吧,兄弟们啊,但是这个正则他可能出现了两次啊,那这个时候你可以把它提出去,哎,就是开始。
08:10
开始标记,所以说你现在就可以把这个提出去叫做start Rep啊,Resp表示的是正则表达式regular expression。啊,但是这块也可以加补货,因为test的时候也可以把补货加上去啊。这样。哎,这样的话,我们这个正则就不用写两遍了,就是如果我这个开始标记检测它啊,这样的OK,我们再测试一下没有问题啊,就提一个变量。好,开始标记我们的检测上了。那开始标记检测到之后,接下来我们要检测结束标记啊,那你说老师开始标记那么好检测结束标记是不是也好检测,对他最难检测的就是内容啊,就是它里面这个内容到底是呃什么意思,一会我们来说啊。好,那这个时候我们就l if。哎,识别这个字符是不是一个结束标签。
09:06
所以我们在这里要加上结束标记,叫n re。好,我们来看结束标签,结束标签的话呢,其实呢,它这里有一个非常显著的一个斜杠。啊,我们每一个结束标签在这里都有一个这样的一个斜杠啊,所以在这里加上就可以了,所以这就结束,如果结束标签test我们的rest。好啊,那这个时候呢,我们当然这个指针要去后移多少。哎,加三,因为这个是占三位是吧,哎,所以这个时候要占三位啊。占三位,OK,没问题,那我们这个时候就要把这个tag给拿到。结束标记,那这个时候我们就输出检测到结束标记啊,好刷新呃,Else,这个指针没有移动,就是在平时的情况下,这个指针要移动,要不然他就死循环了,果不其然死循环了,好我们的新建一个打开啊,这个时候你就会发现开始div,开始H3,开始H3啊,对不起,这块应该是结束。
10:17
对吧,哎,开始div,开始H3结束H3开始ul,开始力结束力,开始力结束力,开始力结束力啊,然后是结束ul结束div啊,这个就相当于标记就已经被寻找出来了。那么这个时候你就会发现,如果不是开始标记,也不是结束标记,当然还有一种情况就是自封闭标签啊,自封闭标签的检测呢,是比较麻烦的啊,我们后面我们再说。哎,自封闭标签,那这个时候我们先不考虑它。先不考虑它的话呢,我们这个时候就会发现,在其他情况下,那这里的文字呢,就都是文字。啊,其他的情况下,就这个时候他就相当于是标签中的文字,因为我们现在他一上来一定是一个标签开始的。
11:07
啊,这是咱们的一个要求,就好比我们之前的题目,它一定是一个数字开始的,对吧,咱们之前题目说了,他不能一上来没有数字啊,这个题目是一样的,就是咱们的标签,它是要一个唯一的一个这个根啊。这样子的。那这个时候的话,你就有出战入战思想了啊,其实他这个思路是差不多的,所以我们这个时候可以准备两个站,就是准备两个站啊,其实没有源码是只准备了一个站,但是呢,嗯,老师觉得就是他那种写法就是嗯。有点太复杂啊,咱们现在就准备两个站。这样的话呢,就相当于换了,就是咱们的算法效率可能是两个站开辟了两个空间啊,但是呢,我们代码更好懂,好,那就是大一。然后是STA2OK,准备了两个站,然后这个时候你就会发现,当如果说有这个标开始标记的时候,那我这个时候就是将这个开始标记是不是推入。
12:11
对吧,哎,推入战中。啊,所以我这个时候就,就让一。Push这个tag。哎,然后呢,我们也要将空数组。啊,是不是去推入啊,呃,是推入战二中。好在我们的储备案例当中呢,我们已经了解了啊这样子的,然后当我们出战的时候,这个时候的话,他就比较麻烦啊,对吧,哎,当我们呃,这个空数组我们就在这推。啊,然后标签中的文字就比较麻烦,我们先去输出两个站的内容,cons.log stack1和STACK2。好,那这个时候我们就可以输出看一下这个站的情况。
13:01
对吧,哎,这是第五啊,然后这里头的话,呃,是因为它便利到了文字对吧,然后如果说呃,当我遇见这个结束标签的时候,我这个时候是不是就需要谈战,因为你遇见的结束标签一定是就是你,呃,因为你想啊。这个力肯定是最后进的,那这个杠力肯定是弹最后进的对吧,封闭标签一定是封的是最后进的啊HTML不就这样吗?就是他肯定是,呃,这里边都清空之后,这个ul才能谈战。啊,所以说他这个就直接谈站就行啊,他谈的站一定是啊和这个标签是一致的啊,就是说你当前占顶的这个人一定是和你识别到的结束标签是一致的,如果不一致的话,就说明你有一个标签没封闭。明白吗?哎,所以说我们现在就是检查啊,就是此时这个tag一定是和。呃,我们这个开始啊,占顶啊,就是占衣顶部的,这个是相同的啊,是相同的,为什么是相同的,咱们再解释一下,因为比如说你div进站,H3进站,那现在要出战的一定是当前占顶的,然后ul进站,力进站出站的一定是他占领的,他进站出战的一定是占领的,他进站他出战的一定占领的,然后他们仨等于都出了,出了之后呢,那这个时候这ul不就是当天占领吗?
14:23
对吧,所以这个时候一定是相同的啊,那所以说我们现在要检查就是如果你现在呃,识别到的这个结束标签,它是不是等于等于你占一的占顶,就是占一的Les减一。这不就占顶这一项吗?他一定要等于,哎,如果不等的话,就说明我们就可以死肉new a了。啊,New arrow就是向控制台抛出一个错误对吧?哎,标签没有封闭。啊,就是这个标签没有封闭。哎,这个标签没有封闭。啊,或者把它放到前头去。
15:01
哎,对吧,你没有封闭,那这个时候它相当于这两个是一样的,一样的话,那我这个时候就可以谈战。明白吗?那我大一是不是就可以去pop掉?啊,就可以谈战,没有什么毛病。哎,这样子的,所以说你就会发现这个站,你看它是一开始div啊,H三进来了,然后H3就没了,然后ul进了,这是为什么多,因为文字,咱们每次输出不都是文字吗。对吧,就包括文字我们都在输出啊,那所以说我们现在可以把这个输出语句放到这个if else if里面,这样的话看的就很清楚。啊,所以说你看检测到div了,Div进站检测到H3 h3进站,H3结束了,那么H3出站对吧,然后ul进站力进站力出战,所以是这么做的,那么右边的这些是咱们一会要做的东西啊,就一会右边呢是咱们要去收集对吧?收集这里面内部就是文字是最麻烦的,为什么文字比较麻烦,因为这个文字你不能一位一位的收集。
16:02
对吧,哎,你是不是得收集的是开始标签和结束标签之中的文字,对吧?哎,然后还有一种情况呢,就是比如说这个文字是在这散放的。啊,这个文字在这里是散放的,也是对的,哎,也是对的啊,它也是对的,为什么?因为它是合理的呀,那所以说这个文字的收集难度,它可能是在结束标签,开始标签对吧?哎,钱也有可能是,呃,就是两两个标签之内,那咱们现在只考虑一个,就是开始到结束。之间的这部分啊,我们只考虑这种情况啊,我们这个标签里面的这个文字呢,你如果要去抓取的话呢,那这个时候就会涉及到一个比较重要的一个事情,就是他会不会误把就是这个尖角号H3也当做。对吧,也当做文字,因为他在识别这个空格的时候。大家发现没有,那这个空格和这个拟好对吧,是不是就会把这个空格和这个拟好也识别成一个符号,所以说我们这个时候就需要去验证它,这里头是没有这个减角号的。
17:04
啊,是没有这个左肩角号的。对吧,哎,这部分,然后我们才能把这个拟好抓取,但是如果说你想写的话,可以试着写一写啊,这些都没有关系,大家就大大方方的去写就行了,对吧,哎,就。抓取结束标记前的这样的一个文字啊,那我们现在就可以叫做word,然后word Rep,但是这个正则比较难写。啊,这个政策比较难写,因为你你你现在不能光去识别这个结束标记,我们把这个结束标记放上来,然后。我们现在去写一个,比如说呃,你很不负责任,写了一个点加,然后我们把这原括号去掉,这样写其实是不负责任的,因为这个点它含有了开始标记,所以他就会从这个空格当中呢,把这个开始标记给你抓进去。明白吗?把这个开始标记和这个你好一起抓进去,那这个时候你就很崩溃啊,咱们可以试一试,这是呃,开始,这是结束,然后在else if,我们再加一层啊。
18:05
好,我们再加一层,就是让我们的这个end,不是让我们的word,然后去test这个rest。对吧?哎,那如果它test这个rest的情况下呢,我们这个时候就可以去识别。对吧,变得到这个字符是不是文字。好,那这个时候我们就可以让这个word是我们的rest的match一个word Rep好,那这个时候我们就可以说检测到文字,检测到文字的话,我们可以把这个word对吧?哎,然后这个时候呢,我们可以指针后移这个word lists。啊,然后站我们先不动,哎,我们现在刷新咱们看一下。那现在的话,你看这个时候就出事了啊,这个时候就出事了,这个时候出什么事了呢?你看这跟老师猜测的是一样的。这个时候他是不是就检测到文字尖角号H3,你好了,因为包括这块还有一个换行符和空格啊,实际上你是看不见的,对吧,诶这个。
19:01
啊,这个I irrow啊,E这块拼错了E啊,Errorrrow对吧?哎,Irrow拼错了啊,对吧?哎,他就报div没有封闭,那实际上div是封闭了的,那他为什么会瞎报div没有封闭呢?原因其实很简单,就是因为他误把这个H3也当做就是这个空格嘛,便利到这个空格的时候,这个空格就一直追,追到就包括这个空格在内,然后还有这部分都被当做了是一个文字。因为你这里是点加嘛,点加它是没法识别这个尖角号的,所以这块呢,它不能是点加。啊,它不能是点加,它是必须是不能是尖角号,所以这块你可以写一个,就是说它是任意字符对吧,但是它不能是什么,对,不能是尖角号。明白吗?就是它不能是尖角号,这个这个表示否,它不是尖角号任意字符。哎,这样的话呢,它就比较好啊,这样比较好,但是这样的话,你看他还是抓不到文字啊,还是抓不到文字,你这个时候就应该说检测到文字,Word你有没有发现检测到,我先把这个呃站的输出,我们先给它注释掉。
20:10
站的输出我们先给它注释掉啊,那你看这个文字还是没有检测出来。对吧,哎,这个文字还是没有减,所以他这个比较难写,他这个比较难写啊。好,我们看诶这回好了,所以这个点不要加啊,这个点就错了,所以我们就直接写方括号就行啊,方括号然后不是开始,不是这个开始箭头就行。所以这个时候他是不是就把你好抓到了div h3,你好,H3对吧?ABC,但是呢,他还有一种特例,就是说你如果这个文字没有出现在呃,开始标签后面,结束标签前,而是在结束标签后,开始标签前。比如说在这里写一个哈哈,那这个哈哈,这个哈哈这些文字呢,实际上是在开始标签前,结束标签后,那么这样的情况下呢,你看哈哈哈哈,他实际上是没有被抓到的。
21:00
因为这个哈哈哈哈哈呢,它是出现在了开始标签对吧?诶它是出现在结束标签后和开始标签前。那么咱们今天呢,是不考虑这种情况,这种情况呢,咱们视为非法,但实际上这种情况呢,并不是非法。啊,我们今天呢,不再考虑这么多种情况,因为考虑这么多种情况的话,实上就是一些细枝末节的东西,哎,那这种情况的话,实际上我们要去要组建一个文本节点啊,如果要考虑的话,其实也不难,就是我们要去抓取开始之前的文字啊,然后因为你当前便利的一定不是开始标签,开始标签你l if else if一定是在上面写的,对吧,它是有if else,它是识别一个,它就不再做了。他就不再做了,所以说他是在上面写的开始和结束,大家有发现没有对吧,所以说这个是开始标签,然后这个是结束标签。啊,这是开始标签,然后这是结束标签。发现了吗?这是开始,这是结束。
22:01
对吧,哎,这是个开始,这是个结束。啊,然后呃,所以说你现在遇见了,但是这种情况太特例了,我们就先不考虑啊,先把这个正常情况咱们做出来。啊,所以它就能检测到你好ABC对吧,都非常好啊,检测到文字,那这个文字是什么,是空,为什么这块检测到了一个空文字,因为这个空文字实际上就是这个。啊,我看看啊是ABC对检测到了一个空文字。啊,然后这块也检测到了一个空。对吧,诶,他偶尔也会检测到空啊,就是这样的一种情况吧。啊,你看在这儿。这个标签之前对吧,就他没有文字,所以这种没有文字的话,他其实一会也会被呃,就很误会,因为这种文字的话,你懂的是吧,所以这种文字我们应该还是要处理一下的啊,就说这里都是啊,就说这。检测到了文字,然后检测到了文字之后,我们还是要测试一下它是不是不是全空。能明白吗?哎,不是全空检测到文字啊。对吧,哎,然后咱们还要需要写个且啊是不是文字,并且不能是全空啊,并且不能并且不能是全空。
23:09
啊,全空的文字。哎,全空的话,就是相当于我们现在是这块是杠S加嘛。对吧,哎,就就相当于这个开始到结尾它全是空啊杠S就有换行符有空格对吧,诶rest啊这样子的情况好刷新啊。Test看看怎么回事啊,正则开始结尾。哦,这是rest,抱歉是吧,这样子的啊。好,然后但是这块报错了,所以这块应该加个非对吧,加个非啊。好,你好,但是这块还是有换行,看见吧,还是有换行符,所以这个杠S还是有点不好用。嗯,不是特别好用的话,是因为咱们的这个且不能写在这啊,因为你的且写在这是不对的,为啥呢?因为你的rise大家发没发现是rise的,而我们要检测的是你现在这部分补货的内容。
24:05
明白吗?捕获到的内容,所以说这块不应该这么写啊,应该检测到文字,我们现在就要看这个word是不是全是空。哎,就所以说如果我们现在全是空的这个test对吧,哎,就是开始到结束啊。好检查这个word是全是空啊,那这个时候就全是空。哎,全是空啊,全是空,那这个时候就什么都不做。啊,或者叫不是全时空。对吧,哎,那我加个飞啊,我们把它放里放。哎,这样做,这样做的话,我们看一下,哎这回好点了,你看他是不是那种空换行他就没有了,对吧,就相当于什么呢?就相当于我们现在面上就已经把这个东西给做的很稳了。啊,面上已经把这个玩意做的很稳了,当然还有站的变化,站的变化,我们下个视频我们再着重讲解战到底要发生什么变化,对吧?哎,然后我们这个视频先讲到这里啊,这个视频很成功。
25:08
好,OK。
我来说两句