博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(?<=p)与:nth-child()的相似性分析
阅读量:7113 次
发布时间:2019-06-28

本文共 2472 字,大约阅读时间需要 8 分钟。

标题挺有意思吧,一个来自正则,一个来自 CSS

前者是正则断言,后者是 CSS 选择器。

正则是用来做什么的?匹配字符的。

选择器是用来做什么的?匹配元素的。

既然都是用来“匹配”的,那么,如果二者在一些地方有什么相似之处,应不足为奇。

我发现 (?<=p):nth-child() 就有很强的相似性。

这里容我慢慢道来。

本文假设读者对 CSS 选择器更熟悉些,所以下面的例子都是先 CSS,后正则。

1. 匹配所有元素

假设页面上有 9li,让所有元素的字都变成红色。此处不会使用 :nth-child 的,直接用标签选择器就行了。

li{    color: red;}复制代码

同样的,正则这边也不需要使用
(?<=p)

'123456789'.replace(/./g, '*') // "*********"复制代码

2. 匹配第1个元素

匹配首元素,在CSS 可以用 :first-child 选择器:

li:first-child{    color:red;}复制代码

而正则可以使用
^ 位置匹配符:

'123456789'.replace(/^./g, '*') // "*23456789"复制代码

而我们知道 :first-child 其实是 :nth-child 的特例:

li:nth-child(1){    color:red;}复制代码

相应的,正则其实也可以用 (?<=p)

'123456789'.replace(/(?<=^)./g, '*') // "*23456789"复制代码

(?<=^) 断言其实匹配的是一个位置,^ 之后的位置,当然还是开头。可以参考对位置的讲解。

3. 匹配第3个元素

CSS 里要匹配第 3 个元素,:nth-child(3) 即可

li:nth-child(3){    color:red;}复制代码

而正则这边呢?这里需要转个弯,要匹配第
3 个,其实是说该字符前面还有
2 个:

'123456789'.replace(/(?<=^.{2})./g, '*')  // "12*456789"复制代码

4. 匹配前3个元素

我们知道 :nth-child 选择器厉害之处是在于它支持 an+b 表达式,比如匹配前 3 个:

li:nth-child(-n+3){    color:red;}复制代码

正则这边,要匹配的字符前面有
0
2 个字符,

'123456789'.replace(/(?<=^.{0,2})./g, '*')  // "***456789"复制代码

5. 匹配奇数位

CSS 这边使用 2n+1

li:nth-child(2n+1){    color:red;}复制代码

正则这边,要匹配的字符前面有
0
2
4...个字符,

'123456789'.replace(/(?<=^(.{2})*)./g, '*')  // "*2*4*6*8*"复制代码

类似的匹配偶数位,即要匹配的字符前面有 135...个字符:

'123456789'.replace(/(?<=^(.)(.{2})*)./g, '*')  // "1*3*5*7*9"复制代码

6. 更一般的 an+b

比如 CSS 这边使用 4n+3

li:nth-child(4n+3){    color:red;}复制代码

正则这边变成了:

'123456789'.replace(/(?<=^(.{4})*.{2})./g, '*')  // "12*456*89"复制代码

即:要匹配的字符前面还有 4n+2 个字符

7. (?=p) 与 :nth-last-child

我们知道 :nth-child 还有对应的 :nth-last-child。它的意思是,与 :nth-child 相反,不是从前往后数,而是从后面向前数,比如要匹配后 3li

li:nth-last-child(-n+3){    color:red;}复制代码

正则这边呢?
(?<=p) 表示
p 后面的位置,与之相对的是
(?=p),表示
p 前面的位置。因此要匹配后
3 个字符:

'123456789'.replace(/.(?=.{0,2}$)/g, '*')  // "123456***"复制代码

更多的,与前几条类似,这里就不写了。

8. (?<!p) 与 :not(:nth-child())

CSS 中,要匹配除了第 3 个元素之外的所有元素,可以配合使用 :not选择器来实现“补集”。

li:not(:nth-child(3)){    color:red;}复制代码

(?<=p) 表示
p 后面的位置。而
(?<!p) 有点绕,它表示所有位置中,不是
p 后面的那个位置,或者说当下位置的前面不是
p

'123456789'.replace(/(?

9. :nth-child(n+3):nth-child(-n+7)

:nth-child 除了取补,还可以取交集,比如匹配第 3-7 个元素

li:nth-child(n+3):nth-child(-n+7){    color:red;}复制代码

(?<=p) 也可以支持交集的

'123456789'.replace(/(?<=^.{2,})(?<=^.{0,6})./g, '*')  // "12*****89"复制代码

交并补,还有并集,CSS 很简单:

li:nth-child(3),li:nth-child(7){    color:red;}复制代码

正则呢,有
| 就是来做这个:

'123456789'.replace(/(?<=^(.{2}|.{6}))./g, '*') // "12*456*89"复制代码

自此,这么一条条看下来,发现了二者确实有多相似之处。

这种跨界比较,我觉得很有趣!

本文完。

另外,欢迎继续阅读本人的。

转载地址:http://pywel.baihongyu.com/

你可能感兴趣的文章
小程序flex-direction
查看>>
编程基本功(一)
查看>>
迭代器随笔
查看>>
flex布局居中无效果注意是否设置了宽度
查看>>
Bootstrap学习笔记系列5------Bootstrap图片显示
查看>>
CentOS服务器下对mysql的优化
查看>>
linux内核模块开发
查看>>
android 小结
查看>>
【转】Android 基于Socket的聊天室
查看>>
小记录
查看>>
ubuntu安装完无法用xshell,远程链接
查看>>
C# 对象哈希码
查看>>
高效的JS数组操作
查看>>
Oracle计算时间差函数
查看>>
Jenkins入门系列之——01第一章 Jenkins是什么?
查看>>
在Ubuntu上搭建hive环境
查看>>
二分法查找
查看>>
hmac检验客户端合法性
查看>>
python-webbrowser模块 浏览器操作
查看>>
map侧连接
查看>>