Javascript 正则表达式遵循模式,大括号之间除外

Javascript 正则表达式遵循模式,大括号之间除外,javascript,regex,Javascript,Regex,我很难在Javascript实现中找到一个干净的正则表达式,它将按照模式捕获尽可能多的行,但是大括号内的任何东西都不需要遵循模式。我不确定最好的解释方法,除了举例: 例如: 假设模式是,直线必须以0开头,以0结尾,但中间只允许1、2或3的序列,所以我使用^0[123]+0。这应该与字符串的第一部分匹配: 0213123123130 012312312312303123123 01231230123123031230 etc. 大括号内的0不会过早结束捕获,即使模式正确 0

我很难在Javascript实现中找到一个干净的正则表达式,它将按照模式捕获尽可能多的行,但是大括号内的任何东西都不需要遵循模式。我不确定最好的解释方法,除了举例:

例如: 假设模式是,直线必须以0开头,以0结尾,但中间只允许1、2或3的序列,所以我使用^0[123]+0。这应该与字符串的第一部分匹配:

0213123123130 012312312312303123123 01231230123123031230 etc. 大括号内的0不会过早结束捕获,即使模式正确

01213123123123{21310030123012301}31231230123
编辑:现在,我知道我可以做一些像^0[123]*?:{.*}*?[123]*?也许是0?但这只适用于只有一组大括号的情况,现在我必须复制我的[123]模式。随着[123]模式变得越来越复杂,让它在正则表达式中多次出现开始变得非常难以理解。类似的东西似乎很有希望,但我不知道如何在这里应用它。使用疯狂的环顾世界似乎是现在唯一的方法,但我希望有一种更干净的方法。

另一种方法怎么样?检查已删除卷曲标记的字符串:

const string='01232121221231{随便3个垃圾?我想要。}1212313123120123{foo}123'; const stringWithoutTags=string.replace/\{.*.\}/g; const result=/^0[123]+0/.teststringWithoutTags;
由于您已指定希望包含垃圾的整个匹配,因此可以使用^0[123]+?:{[^}]*}[123]**0并使用$1获取0之间的部分,或使用$0获取匹配的所有内容

下面是关于正则表达式如何工作的概述:

^将比赛锚定为从线的开头开始 0与文本零字符匹配 [123]+?:{[^}]*}[123]**是一个捕获组,它捕获其中的所有内容。 [123]+匹配1、2或3的一个或多个实例 ?:{[^}]*}[123]**是非捕获组。也就是说,它将是比赛的一部分,但不会有美元用于替换或比赛。 {[^}]*}匹配文字{后跟任意数量的非}字符,后跟} [123]*匹配1、2或3的零个或多个实例 然后,整个非捕获组可以匹配0次或更多次。 这个正则表达式背后的过程称为展开循环。对它有很好的描述。有一些拼写错误修正

展开循环技术基于以下假设: 大多数情况下,你[知道]在[重复]交替中,哪种情况应该是 最常见的,哪一个是例外。我们将称之为第一 第一种是正常情况,第二种是特殊情况。将军 展开循环技术的语法可以写成:

正常*特殊正常**

这可能意味着,如果你找到一个 特殊情况下,匹配它比正常情况下再次匹配。[你会]注意到的 这种语法的这一部分可能[潜在地]导致超线性 匹配

使用Regextest和Regexmatch的示例:

常量字符串=[ '0213123123130', '012312312312303123123', '01231230123123031230', '01213123123123{21310030123012301}31231230123', '01212121{hello 0}121312', '012321212212311{随便3个垃圾?我要。}1212313123120123', '01232121221231{随便3个垃圾?我想要。}121231{额外垃圾}31231201223', ]; 常量正则表达式=/^0[123]+?:{[^}]*}[123]**0/ 控制台。记录“测试” console.logstrings.mapstring=>`${string}':${regex.teststring}` console.log'matches'; 让匹配=字符串 .mapstring=>regex.execstring .mapmatch=>match?匹配[1]:未定义;
控制台。日志匹配 你说你需要捕捉一切,包括胡言乱语,所以我认为这样一个简单的模式应该有效:

^(0(?:[123]|{.+?})+0)
它允许一个以0开头的字符串,然后是任何模式字符1、2或3,或者一个{gibberish}节,并允许重复该操作以处理多个gibberish节,最后必须以0结尾

你可以用

^0[123]*(?:{[^{}]*}[123]*)*0
^字符串开头 0与0匹配 [123]*匹配0+次1、2或3 ?:非捕获组 {[^{}]*}[123]*从开始到结束的匹配}后跟0+1、2或3 *关闭组并重复0+次 0与0匹配
我知道这是怎么回事,但我还需要捕获匹配的片段,包括原始字符串中的所有{gibberish},而不仅仅是测试它是真是假。有没有办法用这个方法做到这一点?我借用了你的regex101代码,对它做了一点修改。看起来这样行吗^0[123]+?:{[^}]*}*?[123]**0但我担心需要进行7次匹配?我编写的正则表达式匹配所有内容,而无需更新。只需要108步。0[123]+?:{[^}]*}[123]**0. 如果您只需要匹配0之间的内容,0[123]+?:{[^}]*}[123]**0将适用于此。如果您需要匹配所有内容,^0?:[123]{.+?}+0将适用于此,而无需复制[123]。这是非常正确的。我的复制品是有意的
nal是为了优化。对于少量的匹配项,这不会成为问题,但是如果有大量的匹配项或大量的垃圾段,使用交替运算符和惰性运算符可能不是最好的方法。@CarySwoveland,很抱歉造成混淆。我一定错过了插入符号,但谢谢你把胡萝卜放在大棒之前,让我知道我的错误。我利用编辑的机会添加了更多关于正则表达式如何工作以及其结构背后的前提的信息。我忽略了大括号内的模式,是的,但我仍然希望在捕获中包含大括号的内容。0123{5}670不匹配,因为它在大括号外包含67个大括号,而[123]中未包含该大括号。我在大括号内包含了0的示例,以表明即使模式继续正确,模式也不应过早地在大括号内结束。@CarySwoveland我对文本做了一些更改以澄清。@CarySwoveland在编辑中我确实将问题更改为“行必须以0开头”。我选择的答案是我需要的,减去^。
^0[123]*(?:{[^{}]*}[123]*)*0