We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
标题挺有意思吧,一个来自正则,一个来自 CSS。
CSS
前者是正则断言,后者是 CSS 选择器。
正则是用来做什么的?匹配字符的。
选择器是用来做什么的?匹配元素的。
既然都是用来“匹配”的,那么,如果二者在一些地方有什么相似之处,应不足为奇。
我发现 (?<=p) 与 :nth-child() 就有很强的相似性。
(?<=p)
:nth-child()
这里容我慢慢道来。
本文假设读者对 CSS 选择器更熟悉些,所以下面的例子都是先 CSS,后正则。
假设页面上有 9 个 li,让所有元素的字都变成红色。此处不会使用 :nth-child 的,直接用标签选择器就行了。
9
li
:nth-child
li{ color: red; } 复制代码
'123456789'.replace(/./g, '*') // "*********" 复制代码
匹配首元素,在CSS 可以用 :first-child 选择器:
: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" 复制代码
(?<=^) 断言其实匹配的是一个位置,^ 之后的位置,当然还是开头。可以参考《JS正则迷你书》对位置的讲解。
(?<=^)
CSS 里要匹配第 3 个元素,:nth-child(3) 即可
3
:nth-child(3)
li:nth-child(3){ color:red; } 复制代码
2
'123456789'.replace(/(?<=^.{2})./g, '*') // "12*456789" 复制代码
我们知道 :nth-child 选择器厉害之处是在于它支持 an+b 表达式,比如匹配前 3 个:
an+b
li:nth-child(-n+3){ color:red; } 复制代码
0
'123456789'.replace(/(?<=^.{0,2})./g, '*') // "***456789" 复制代码
CSS 这边使用 2n+1:
2n+1
li:nth-child(2n+1){ color:red; } 复制代码
4
'123456789'.replace(/(?<=^(.{2})*)./g, '*') // "*2*4*6*8*" 复制代码
类似的匹配偶数位,即要匹配的字符前面有 1、3、5...个字符:
1
5
'123456789'.replace(/(?<=^(.)(.{2})*)./g, '*') // "1*3*5*7*9" 复制代码
比如 CSS 这边使用 4n+3
4n+3
li:nth-child(4n+3){ color:red; } 复制代码
正则这边变成了:
'123456789'.replace(/(?<=^(.{4})*.{2})./g, '*') // "12*456*89" 复制代码
即:要匹配的字符前面还有 4n+2 个字符
4n+2
我们知道 :nth-child 还有对应的 :nth-last-child。它的意思是,与 :nth-child 相反,不是从前往后数,而是从后面向前数,比如要匹配后 3 个 li:
:nth-last-child
li:nth-last-child(-n+3){ color:red; } 复制代码
p
(?=p)
'123456789'.replace(/.(?=.{0,2}$)/g, '*') // "123456***" 复制代码
更多的,与前几条类似,这里就不写了。
在 CSS 中,要匹配除了第 3 个元素之外的所有元素,可以配合使用 :not选择器来实现“补集”。
:not
li:not(:nth-child(3)){ color:red; } 复制代码
(?<!p)
'123456789'.replace(/(?<!^.{2})./g, '*') // "**3******" 复制代码
:nth-child 除了取补,还可以取交集,比如匹配第 3-7 个元素
7
li:nth-child(n+3):nth-child(-n+7){ color:red; } 复制代码
'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" 复制代码
自此,这么一条条看下来,发现了二者确实有多相似之处。
这种跨界比较,我觉得很有趣!
本文完。
另外,欢迎继续阅读本人的《JS正则迷你书》。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
标题挺有意思吧,一个来自正则,一个来自
CSS
。前者是正则断言,后者是
CSS
选择器。正则是用来做什么的?匹配字符的。
选择器是用来做什么的?匹配元素的。
既然都是用来“匹配”的,那么,如果二者在一些地方有什么相似之处,应不足为奇。
我发现
(?<=p)
与:nth-child()
就有很强的相似性。这里容我慢慢道来。
本文假设读者对
CSS
选择器更熟悉些,所以下面的例子都是先CSS
,后正则。1. 匹配所有元素
假设页面上有
9
个li
,让所有元素的字都变成红色。此处不会使用:nth-child
的,直接用标签选择器就行了。(?<=p)
。2. 匹配第1个元素
匹配首元素,在
CSS
可以用:first-child
选择器:^
位置匹配符:而我们知道
:first-child
其实是:nth-child
的特例:相应的,正则其实也可以用
(?<=p)
:(?<=^)
断言其实匹配的是一个位置,^
之后的位置,当然还是开头。可以参考《JS正则迷你书》对位置的讲解。3. 匹配第3个元素
CSS
里要匹配第3
个元素,:nth-child(3)
即可3
个,其实是说该字符前面还有2
个:4. 匹配前3个元素
我们知道
:nth-child
选择器厉害之处是在于它支持an+b
表达式,比如匹配前3
个:0
到2
个字符,5. 匹配奇数位
CSS
这边使用2n+1
:0
、2
、4
...个字符,类似的匹配偶数位,即要匹配的字符前面有
1
、3
、5
...个字符:6. 更一般的 an+b
比如
CSS
这边使用4n+3
正则这边变成了:
即:要匹配的字符前面还有
4n+2
个字符7. (?=p) 与 :nth-last-child
我们知道
:nth-child
还有对应的:nth-last-child
。它的意思是,与:nth-child
相反,不是从前往后数,而是从后面向前数,比如要匹配后3
个li
:(?<=p)
表示p
后面的位置,与之相对的是(?=p)
,表示p
前面的位置。因此要匹配后3
个字符:更多的,与前几条类似,这里就不写了。
8. (?<!p) 与 :not(:nth-child())
在
CSS
中,要匹配除了第3
个元素之外的所有元素,可以配合使用:not
选择器来实现“补集”。(?<=p)
表示p
后面的位置。而(?<!p)
有点绕,它表示所有位置中,不是p
后面的那个位置,或者说当下位置的前面不是p
。9. :nth-child(n+3):nth-child(-n+7)
:nth-child
除了取补,还可以取交集,比如匹配第3
-7
个元素(?<=p)
也可以支持交集的交并补,还有并集,
CSS
很简单:|
就是来做这个:自此,这么一条条看下来,发现了二者确实有多相似之处。
这种跨界比较,我觉得很有趣!
本文完。
另外,欢迎继续阅读本人的《JS正则迷你书》。
The text was updated successfully, but these errors were encountered: