这是我的正则表达式:
"button:not([DISABLED])".match(/\([^()]+\)|[^()]+/g);
结果是:
["button:not", "([DISABLED])"]
这是对的吗?我糊涂了。因为(管道)运算符|
表示“或”,我认为正确的结果是:
["button:not", "[DISABLED]", "([DISABLED])"]
因为:
["button:not", "[DISABLED]"]
是结果:
"button:not([DISABLED])".match(/[^()]+/g);
和此:
["([DISABLED])"]
是结果:
"button:not([DISABLED])".match(/\([^()]+\)/g);
但是控制台中的结果输出告诉我结果是:
["button:not", "([DISABLED])"]
问题出在哪里?
答案 0 :(得分:55)
正则表达式
/\([^()]+\)|[^()]+/g
基本上说:有两个选项,匹配(1)\([^()]+\)
或(2)[^()]+
,无论你在哪里看到(/g
)
让我们迭代您的样本字符串,以便了解获得结果背后的原因。
开始字符串:button:not([DISABLED])
。
b
开始(实际上它从字符串开始的锚点^
开始,但对于此示例,它无关紧要) b
只能匹配(2),因为(1)需要开始 (
。
(
或 )
。t
字符(因为下一个是 (
且不匹配{ {1}})因此将[^()]+
作为第一个匹配的字符串。button:not
。它是否开始匹配任何选项?是的,第一个:(
。
\([^()]+\)
< / strong>或 (
直到找到 )
(如果在消费时发现<<在 )
之前强> (
,它会回溯,因为这意味着(1)正则表达式最终不匹配) )
,然后将)
作为第二个匹配的字符串。
编辑:有一个非常有用的online tool,可让您以图形形式查看正则表达式。也许有助于理解正则表达式如何工作:
您也可以逐步移动光标,看看我上面尝试解释的内容: live link 。
请注意由([DISABLED])
分隔的表达式的优先级:由于JavaScript正则表达式引擎处理字符串的方式,表达式显示的顺序很重要。它将按照给出的顺序评估每个备选方案。如果其中一个选项与末尾匹配,则不会尝试匹配任何其他选项,即使它可以。希望一个例子让它更清晰:
|
答案 1 :(得分:14)
您对交替运算符的理解似乎不正确。它不会查找所有可能的匹配项,仅适用于匹配的第一个(从左到右)。
将(a | b)
视为“匹配 a
或 b
”。
答案 2 :(得分:0)
我对正则表达式不太了解,但我认为它们的工作方式是给你一个匹配它们的东西,而不是所有可以匹配它们的东西。
所以,|
运算符说:“给我一些与左正则表达式匹配的东西,或与正则正则表达式匹配的东西”。
由于你的字符串包含与左正则表达式匹配的东西,你就可以得到它。
答案 3 :(得分:-1)
Regex找到最佳匹配,而不是所有可能的匹配。该正则表达式的最佳匹配是"([DISABLED])"
,而不是"[DISABLED]"
,它是“更好”匹配的子集。
考虑以下示例:
"123 456789".match( /[0-9]{4,6}/g )
您想要找到长度在4到6位之间的一个数字。 如果结果将是与正则表达式匹配的所有可能数字,那么它将没有多大用处:
[ "4567", "5678", "6789", "45678", "56789", "456789" ] // you don't want this