我一直在js学习regexp遇到了一个我不理解的情况.
我使用以下正则表达式对replace函数进行了测试:
/\W*/g
Run Code Online (Sandbox Code Playgroud)
并且期望它在字符串的开头前面并继续替换所有非单词字符.
The Number is (123)(234)
Run Code Online (Sandbox Code Playgroud)
会成为:
_The_Number_is__123___234_
Run Code Online (Sandbox Code Playgroud)
这将是字符串的前置,因为它至少有零个实例,然后替换所有非中断空格和非单词字符.
相反,它会在每个字符前面添加并替换所有非字符.
_T_h_e__N_u_m_b_e_r__i_s__1_2_3__2_3_4__
Run Code Online (Sandbox Code Playgroud)
为什么这样做?
问题在于\W*.它表示"0个或更多非单词字符".这意味着空字符串""将匹配,因为它确实是0个非字字符.
因此,正则表达式在字符串中的每个字符之前和结尾处匹配,因此为什么所有替换都已完成.
您想要/\W/g(替换每个单独的非单词字符)或/\W+/g(替换每组连续的非单词字符).
"The Number is (123)(234)".replace(/\W/g, '_') // "The_Number_is__123__234_"
"The Number is (123)(234)".replace(/\W+/g, '_') // "The_Number_is_123_234_"
Run Code Online (Sandbox Code Playgroud)
JS正则表达式引擎将字符串解析为它们之间的字符和位置序列.请参阅下图,其中我用连字符标记了位置:
-T-h-e- -N-u-m-b-e-r- -i-s- -(-1-2-3-)-(-2-3-4-)-
||| |
||Location between T and h, etc. ............. |
|1st symbol |
start -> end
Run Code Online (Sandbox Code Playgroud)
所有这些职位都可以用正则表达式进行分析和匹配.
由于.replace(/\W/g, '_')是正则表达式匹配0和更多(由于量词)非单词字符的所有非重叠事件(由于*修饰符),所以字字符之前的所有位置都匹配.在和之间,有一个使用正则表达式测试的位置,并且由于没有非单词char(是单词char),返回空匹配(因为可以匹配空字符串)..replace(/\W+/g, '_')*+/\W*/gg
所以,你需要用一个替换字符串的开头和每个非字的字符*.天真的方法是使用T.但是,有一个警告:如果一个字符串以非单词字符开头,则不会h在字符串的开头附加任何字符串:
console.log("Hi there.".replace(/\W|^/g, '_')); // _Hi_there_
console.log(" Hi there.".replace(/\W|^/g, '_')); // _Hi_there_Run Code Online (Sandbox Code Playgroud)
请注意,此处h在交替时首先出现,在字符串开头匹配时为"wins":空间匹配,然后在下一次匹配迭代时找不到起始位置.
你现在可能认为你可以匹配\W*.看这里:
console.log("Hi there.".replace(/^|\W/g, '_')); // _Hi_there_
console.log(" Hi there.".replace(/^|\W/g, '_')); // _ Hi_there_Run Code Online (Sandbox Code Playgroud)
所述_第二结果表示JS的正则表达式引擎如何替换操作期间处理零宽度匹配:一次零宽度匹配(在这里,它是在字符串的开始时的位置)被发现,发生置换,并且.replace(/\W|^/g, '_')属性被递增,因此前进到第一个角色后的位置!这就是为什么第一个空间被保留,不再匹配的原因_.
解决方案是使用不允许零宽度匹配的消费模式:
console.log("Hi there.".replace(/^(\W?)|\W/g, function($0,$1) { return $1 ? "__" : "_"; }));
console.log(" Hi there.".replace(/^(\W?)|\W/g, function($0,$1) { return $1 ? "__" : "_"; }));Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4742 次 |
| 最近记录: |