Javascript 有没有一种有效的方法来测试字符串是否包含与正则表达式数组匹配的非重叠子字符串?

Javascript 有没有一种有效的方法来测试字符串是否包含与正则表达式数组匹配的非重叠子字符串?,javascript,regex,string,algorithm,Javascript,Regex,String,Algorithm,我只想测试一个字符串是否包含非重叠的子字符串,以以下方式匹配正则表达式数组:如果子字符串匹配数组的某个项,请从数组中删除相应的正则表达式,然后继续。我需要一个函数func(arg1,arg2),它将接受两个参数:第一个是字符串本身,第二个是要测试的正则表达式数组。 我读过一些解释(例如),但它们没有回答这个具体问题。例如,在Javascript中,以下三个代码片段将返回true: /(?=ab)(?=abc)(?=abcd)/gi.test("eabzzzabcde"); /(?=.*ab)(?

我只想测试一个字符串是否包含非重叠的子字符串,以以下方式匹配正则表达式数组:如果子字符串匹配数组的某个项,请从数组中删除相应的正则表达式,然后继续。我需要一个函数
func(arg1,arg2)
,它将接受两个参数:第一个是字符串本身,第二个是要测试的正则表达式数组
我读过一些解释(例如),但它们没有回答这个具体问题。例如,在Javascript中,以下三个代码片段将返回
true

/(?=ab)(?=abc)(?=abcd)/gi.test("eabzzzabcde");
/(?=.*ab)(?=.*abc)(?=.*abcd)/gi.test("eabzzzabcde");
/(?=.*?ab)(?=.*?abc)(?=.*?abcd)/gi.test("eabzzzabcde");
这显然不是我想要的(因为
“abc”
“abcd”
中的
“eabzzabcde”
只是以重叠的方式混合在一起)。因此,
func(“eabzzzabcde”,[/ab/gi,/abc/gi,/abcd/gi])
应该返回
false

但是,
func(“Fhh,fabcw wxabcdy yz…zab.”,[/ab/gi,/abc/gi,/abcd/gi])
应该返回
true
,因为
“ab”
“abc”
“abc”
子字符串都不重叠。逻辑如下。我们有一个正则表达式数组:
[/ab/gi,/abc/gi,/abcd/gi]
,以及一些可能的原始字符串的三个(其中3等于该数组的长度)不重叠、独立的子字符串的组合:
fabcw
xabcdy
zab.
fabcw
是否匹配
/abc/gi
?对好的,我们从数组中删除
/abc/gi
,我们有
[/ab/gi,/abcd/gi]
用于
xabcdy
zab。
xabcdy
是否匹配
/abcd/gi
?对好的,我们将
/abcd/gi
从当前的数组中删除,我们将
[/ab/gi]
用于
zab。
是否匹配
/ab/gi
?对当前数组中没有剩余的正则表达式,我们总是回答“是”,因此-return
true
这里棘手的部分是找到一种有效的(这样性能就不会太糟糕)方法来获得至少一个可能的非重叠子字符串的“良好”组合。

更复杂的情况是,例如
func(“acdxbaab ababacb”、[/.*a.*b.*c/gi、/.*c.*b.*a/gi])
。使用上述逻辑,我们可以看到,如果我们取原始字符串的两个不重叠部分-
“acdxba”
(或
“cdxba”
)和
“abaac”
(或
“abaacb”
“babaac”
等)-第一个匹配
/.*c.*b.*a/gi
,第二个匹配
/.*a.*b.*c/gi
。因此,
func(“acdxbaab ababacb”、[/.*a.*b.*c/gi、/.*c.*b.*a/gi])
应该返回
true


有什么有效的方法可以解决这样的问题吗?

假设每个模式只匹配一次,那么我们就可以为它们的所有排列构造一个regexp:

const模式=['ab','abc','abcd'];
const input=“Fhh,fabcw wxabcdy yz…zab。”;
//创建表单的regexp
//(*ab.*abc.*abcd.*
功能构建(模式){
返回`(${[',…patterns,'].join('.*?')})`;
}
功能匹配(输入、模式){
常量regexps=[…排列(模式)].map(构建);
//创建表单的regexp
///(*ab.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*/
const regexp=new regexp(regexps.join('|');
返回regexp.test(输入);
}
//简单置换生成器。
函数*排列(a,n=a.length){

如果(n Well
.test()
只是给出一个关于它是否匹配的是/否答案,但是如果使用
.exec()
(或
.match()
),您会得到字符串中匹配内容及其索引的详细信息,因此您应该能够使用它来检查重叠。关于
“Fhh,fabcw wxabcdy yz…zab。”
,这些子字符串确实相互重叠,因为
/ab/gi
将在该输入字符串中匹配三次。一种可能性(可能不是最好的,可能有点混乱):对于每个正则表达式,列出每个匹配子字符串的索引和长度,然后比较所有正则表达式的列表以找到不重叠的匹配项。您的测试用例:
func(“Fhh,fabcw wxabcdy yz…zab.”,[/ab/gi,/abc/gi,/abc/gi,/abcd/gi])
。我认为这应该返回
false
,而不是
true
(所有在“wxabcdy”中重叠)。@nnnnnn@Makyen:“关于您的“Fhh,fabcw wxabcdy yz…zab”示例,这些子字符串确实相互重叠,因为/ab/gi将在该输入字符串中匹配三次”/“wxabcdy”中的所有重叠"-一些正则表达式匹配多少次或在哪里相互重叠并不重要。重要的是我们可以为每个匹配提取三个不重叠的子字符串-例如
fabccw
xabcdy
zab.
fabcw
匹配
/abc/gi
xabcdy
匹配
/gi
zab.
匹配
/ab/gi
。我们看到,对于每个正则表达式,我们都有单独的子字符串匹配它。但是'xabcdy'匹配所有的
/abc/gi
/abc/gi
/ab/gi
。并且,
fabcw
同时匹配
/abc/gi
/ab/gi这里不需要重叠,因为较短的正则表达式是较长正则表达式的子集(即,较短的正则表达式将始终匹配较长正则表达式的所有实例)。显然,如果我有相对较多的正则表达式,这种方法不起作用。构造如此庞大的
/(.*ab.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*abc.*),需要太多的排列|…/
regex!我在Firefox中测试了这一点(例如,对于
const模式=['ab',abc',abcd','xy','xyy','xyzz','bx','baz'])
const inpu