给定两个字符串(记为A和B)和一组字符串N ,我需要编写一个正则表达式来测试给定的输入字符串W是否包含子字符串S,其中S是满足以下所有三个条件的任意子字符串:1. 以 A 开头;2 . 以B结尾;3. N中的任何元素都不出现在A和B之间的部分(此部分不与A和B重叠)。
例如,我选择了"ab"
as A,"bc"
as B,["a", "cb", "cd"]
as N。如果"ec"
是内部部分,那么就是满足所有三个条件的"abecbc"
字符串:如果W包含这样的子字符串,则正则表达式必须返回。我的第一个变体是以下正则表达式:true
var T = /(?=ab.*bc)(?=(?!ab.*a.*bc))(?=(?!ab.*cb.*bc))(?=(?!ab.*cd.*bc))/;
我选择了W = S = "abecbc"
。此正则表达式按预期工作:
T.test("abecbc");
// true
但我对以下问题感兴趣:如何编写功能等效的正则表达式,而不使用正则前瞻(?=)
作为 AND 运算符?
因此我的第二种方案如下:
var R = /ab(?!.*?(?:a|cb|cd).*)bc/;
但R.test("abecbc")
计算结果为false
。因此让我们分成R
三个部分:
/ab(.*)/.test("abecbc")
返回true
。然后
/(.*)bc/.test("abecbc")
返回true
。
"ab"
内部部分(即和之间的部分"bc"
)是"ec"
。并且
/(?!.*?(?:a|cb|cd).*)/.test("ec")
返回true
,这是预期的。因此必须有三个事实,并且 中没有其他部分R
。那么为什么
/ab(?!.*?(?:a|cb|cd).*)bc/.test("abecbc")
评估为false
?以及如何编写正确的正则表达式来解决帖子第一段中描述的问题,而无需使用正向前瞻(?=)
作为 AND 运算符?
编辑
我的问题与此问题不重复:我需要解释为什么特定的正则表达式 ( R
) 返回false
而不是true
。另一个区别是我不需要测试内部部分是否包含指定的字符串。
您尝试的正则表达式
R = /ab(?!.*?(?:a|cb|cd).*)bc/
匹配失败,abecbc
因为负向前瞻模式是零宽度断言,因此您的正则表达式bc
必须紧跟在后面ab
。如果您尝试通过添加.*
之前来修复它bc
,则无法保证在和a|cb|cd
之间匹配。ab
bc
您可以捕获B以及它之后的内容,以便可以使用捕获作为负向前瞻断言的结尾,以避免在A和B之间存在任何N时发生匹配:
演示:https://regex101.com/r/NqLbfV/4