我不确定我是否说得对。
我想用一个正则表达式来满足这两个文本。
text1 = 'foobar';
text2 = 'foobar-baz';
text1 的预期输出
$1
应为bar
$2
应为''
text2的预期输出
$1
应为bar
$2
应为baz
以下是我的尝试:
/foo([a-z0-9\-_=\+\/]+)(\-(.*))?/i
text1
的结果是正确的,但对于text2
,$1
获取完整字符串foobar-baz
答案 0 :(得分:0)
您可以使用非捕获组:
/foo([a-z0-9\-_=\+\/]+)(?:-(.*))?/i
这解决了避免额外捕获组的问题。但是,您的模式仍然存在将-
包含为第一个字符串的有效字符的问题。因此,当你对" foobar-baz"执行模式时,整个片段" bar-baz"将匹配模式中的第一个组。
你必须决定你想要匹配的是什么;您的规则目前与您寻求的结果不一致。如果您从第一组中删除-
:
/foo([a-z0-9_=\+\/]+)(?:-(.*))?/i
然后你得到你说你正在寻找的结果。
答案 1 :(得分:0)
这里的问题是由于-
可能包含在第一个捕获组中。有两种情况:
字符串中有一个或多个-
,您想要选择由连字符分隔的最后一个组。直觉上,我们想到了贪婪的量词,以及一个简单的解决方案,如:
input.match(/foo([a-z0-9_=+\/-]+)-(.*)/)
会起作用。
然而,第二种情况,即字符串中没有-
,与前一种情况相结合,会导致问题。
由于[a-z0-9_=+\/-]+
包含-
,如果你使-(.*)
成为可选项,在第一种情况下给定输入,它将匹配字符串的结尾并将所有内容放在第一个捕获组。
我们需要控制回溯行为,以便当至少有一个-
时,它必须匹配它并匹配最后一个,并允许第一个组在没有{{1}时吞噬所有内容}}
对当前正则表达式进行微小更改的一种解决方案是:
-
延迟量词使引擎首先从最左边的input.match(/foo([a-z0-9_=+\/-]+?)(?:-([a-z0-9_=+\/]*))?$/)
尝试,而锚点-
和最后没有$
的字符类强制引擎仅在最后-
如果有的话。
请注意,如果没有-
,第二个捕获组将为undefined
。
示例输入输出:
-