我正在尝试学习regex
javascript。在进行测试时,我的大脑在看到输出时会感到困惑。
您能否解释一下为什么我的输出结果数组在使用*
in 模式而不是在+
.
PS:输入的只是一个简单的示例字符串来学习。
这是我的示例代码:
a='bb bbbb bbb'
a.match(/(bb)*/g) // O/P is ["bb","","bbbb","","bb","",""]
a.match(/(bb)+/g) // O/P is ["bb","bbbb","bb"]
我正在尝试学习regex
javascript。在进行测试时,我的大脑在看到输出时会感到困惑。
您能否解释一下为什么我的输出结果数组在使用*
in 模式而不是在+
.
PS:输入的只是一个简单的示例字符串来学习。
这是我的示例代码:
a='bb bbbb bbb'
a.match(/(bb)*/g) // O/P is ["bb","","bbbb","","bb","",""]
a.match(/(bb)+/g) // O/P is ["bb","bbbb","bb"]
正则表达式中的*
或Kleene Star表示“零个或多个”,因此它匹配空字符串。
而是表示“一个或多个”,因此它与空字符串+
不匹配。
鉴于我们有如下
a = 'bb bbbb bbb';
让我们这样表示:
a = /^bb bbbb bbb$/;
where^
是字符串的开头,是字符串$
的结尾。
我们的模式是(bb)*
。这意味着引擎将查找两个b
“零次或多次”的序列。这意味着bb
如果找到序列,则模式匹配,否则为空字符串。
现在,我将逐步使用点 ( .
) 来表示正则表达式分析。
脚步
STRING MATCH ARRAY
start - /^.bb bbbb bbb$/ -> [ ]
1 - /^bb. bbbb bbb$/ -> [ "bb" ]
2 - /^bb .bbbb bbb$/ -> [ "bb", "" ]
3 - /^bb bbbb. bbb$/ -> [ "bb", "", "bbbb" ]
4 - /^bb bbbb .bbb$/ -> [ "bb", "", "bbbb", "", ]
5 - /^bb bbbb bb.b$/ -> [ "bb", "", "bbbb", "", "bb" ]
6 - /^bb bbbb bbb.$/ -> [ "bb", "", "bbbb", "", "bb", "", ]
7 - /^bb bbbb bbb$./ -> [ "bb", "", "bbbb", "", "bb", "", "" ]
自从模式匹配一个序列以来,STEP 1
我们已经推送。bb
因为模式匹配空字符串,所以STEP 2
我们已经推送。""
STEP 3
我们推入是bbbb
因为模式匹配了两个序列。
STEP 4
->STEP 2
STEP 5
->STEP 1
因为模式匹配空字符串STEP 6
,所以我们已经推送,因为只找到了一个。""
b
最后你遇到$
令牌,它再次匹配空字符串。
请注意,如果字符串是"bb bbbb bbbb"
数组将是["bb", "", "bbbb", "", "bbbb", ""]
*
表示“匹配前一组零次或多次”。引擎尝试bb
在字符串中第一个之后的位置进行匹配。它找到一个空格,这意味着(bb)
匹配“零次”,导致空匹配。
+
表示“至少匹配前一个组一次”,因此每个匹配项都必须包含bb
您的情况下的字符序列。
解释为什么最后有两个空匹配:
最后一个“词”是bbb
。引擎匹配bb
,这里没问题。然后b
就剩一个了。它匹配(bb)
“零次”。然后它尝试匹配字符串的最后一个位置,即在最后一个字符和字符串末尾之间。它再次匹配 es (bb)
“零次”。
如果你想详细了解正则表达式引擎的工作原理,我推荐《精通正则表达式》这本书。