用正则匹配class时引出的一个疑惑?


在用正则匹配一个特定的className时,发现了一个问题,在此请教一下大家:

比如,一个元素的完整的className是


 var f = "ac   p1     p4     p0 fe   p6     p8   p9 p10 p11 ap7 p3d p12";

我想写一个正则能匹配出全部 只能由

"p"+数字

组合的class。

我自己写的一个正则如下:


 var reg = /(?:\s+|^)p\d+(?:\s+|$)/g;

结果是:


 ["     p1     ", "     p0 ", "   p6     ", "  p9 ", " p11 ", " p12"]

发现其中少匹配了

p4 p8 p10

这里颇为费解,后来我发现规律是相邻的多个“p数字”只会间隔着匹配到!
我分析是因为:前面一个满足条件的匹配项,比如p1,它占据匹配到的前后空格,导致本来符合正则的紧邻的匹配项p4 因为p1匹配项以及占据了后空格(即是后面的匹配项p4的前空格),导致p4自己不符合正则表达式的匹配了而导致匹配不到的。

然后我修改正则为


 var reg = /(?:\s+?|^)p\d+(?:\s+?|$)/g;

增加了一个最小匹配"?"

这是原字符串:


 var f = "ac     p1     p4     p0 fe   p6     p8   p9 p10 p11 ap7 p3d p12";

现在的正则结果变为,


 ["     p1 ", "    p4 ", "    p0 ", "   p6 ", "    p8  ", " p9 ", " p11 ", " p12"]

结果匹配的比之前多了,但是还是没有全部匹配到,其中少了

p10

分析发现第2个正则,对于匹配2个挨着的 “p数字”之间只有1个空格的情况,会出现上述 丢失 的问题。
间隔有1个空格以上可以全部匹配到。

那么问题来了,
正确的正则匹配上述要求应该如何写?
对于第一种正则,它失配的原因到底怎么理解呢?我一直以为第一个正则是能匹配得到的
望大神指点一二!!在此感激不尽!

正则表达式 javascript正则 JavaScript

天下无敌1 8 years, 10 months ago

想复杂了吧?直接用 \bp\d+\b 就可以了。

补充:
第一个正则失败是因为 p1 后面的空格被 p1 匹配了,到了匹配 p4 时,导致 p4 前面没有空格而匹配失败(因为 (?:\s+|^) 用了 + ),其他的类似。

AngelD奏 answered 8 years, 10 months ago

因为第一个表达式中:空格被p1匹配走了,p4匹配不到

thmzy answered 8 years, 10 months ago

\b 匹配单词边界, f.match(/\bp[\d]+\b/g)

keeris answered 8 years, 10 months ago

直接写这样不行么?


 var test = 'ac     p1     p4     p0 fe   p6     p8   p9 p10 p11 ap7 p3d p12';

var res = test.match(/p[\d]+/g);
console.log(res);//[ 'p1', 'p4', 'p0', 'p6', 'p8', 'p9', 'p10', 'p11', 'p7', 'p3', 'p12' ]

wslf123 answered 8 years, 10 months ago

正则写不好,于是就想其他办法,比如先替换所有连续空格为单个空格,然后以空格分解字符串为数组,然后遍历判断。
或者上面说的第一步省掉 :)

子兎Muki answered 8 years, 10 months ago

我觉得前后用环视匹配位置的话,可能就和LZ想的差不多了


 (?:\s|^)(?=p)p\d+(?=\s|$)

吴克的叔叔葛炮 answered 8 years, 10 months ago

Your Answer