我在 Javascript 中有这个示例字符串,"246126667"
我想获取左侧有任何 2 个数字和末尾有 6 的所有子字符串,即["246","126","266","666"]
,我应用match
正则表达式[0-9]{2}6
和参数g
得到结果,但它不像我想要的那样工作。
console.log(
"246126667".match(/[0-9]{2}6/g)
)
问题是它没有返回所有 4 个数字,而是只返回["246","126"]
. 是否可以使用正则表达式解决这个问题?还有其他方法吗?
问题
您使用的表达式 (
[0-9]{2}6
) 很好。为什么它不匹配重叠字符的主要问题是因为正则表达式引擎消耗了它匹配的字符。因此,匹配"126"
后尝试下一场比赛的位置将是:
并且它不会找到另外 3 个以 . 结尾的数字
6
。解决方案
肯定的前瞻尝试匹配,但如果匹配,它会返回到尝试之前的位置。也就是说,它不消耗字符。语法是
所以这个正则表达式将匹配你正在寻找的
但是还有一个补充:因为它不消耗字符,所以它匹配位置,而不是你试图获取的 3 个字符。为此,我们使用一个组(我们用括号括起来)来捕获文本。
此外,需要使用
.exec()
then 获取捕获的文本match[1]
,以及一个额外的条件来避免由于已知的 JavaScript 错误导致的无限循环。正则表达式
代码
为了完成@Mariano 的回答,我将尝试对此事进行更多说明,以便
aserciones positivas
.正如@Mariano 解释的那样,使用以下正则表达式
/[0-9]{2}6/g
,这些将是match
您String
作为示例放置的方法执行的操作:所以,为了防止这种情况发生,你可以做两件事:
1 -使用该方法
exec
并操作lastIndex
正则表达式,将其减去2
,以便下一次搜索从开始后的下一个字符开始match
:2 -或者做@Mariano 推荐的事情:一个
aserción positiva
。但是使用它的正则表达式,您还必须操作该属性
lastIndex
,因为,一个肯定的断言不是它确实match
并返回到开头,match
而是它永远不会从那个地方移动(它不消耗字符,因为它不是一部分的match
)。这不是错误JavaScript
,而是我们明确告诉script
它不要使用任何字符。以正则表达式为例/(?=(\d{2}6))/g
,让我们注意它不会尝试match
处理任何字符,但它所做的是捕获由两个数字组成的组,后跟 a6
,因此我们可以使用exec
.exec
让我们看看该方法在这个正则表达式中会遵循哪些步骤:因此,如果我们使用
exec
带有 awhile
的方法,调用堆栈将充满loop
无穷大,为避免这种情况,我们应该在lastIndex
正则表达式属性中添加一个,以便下match
一个从该位置查找它:没有必要执行条件
match.index === regex.lastIndex
,因为除非我们改变它,否则lastIndex
正则表达式的属性将始终保持等于开头,match
因为在所述表达式中不消耗任何字符。避免更新属性的一种方法
lastIndex
是使用一个消耗字符的正则表达式,例如这个表达式/(?=(\d{2}6))\d/g
。请注意,与@Mariano 放置的唯一不同的是它确实match
生成了一个数字,因此该表达式将消耗字符。让我们按照该方法将遵循exec
此正则表达式的步骤进行操作: