为什么我的RegExp.protype.exec()返回未定义的数组



我有一个正则表达式,如下所示:

/(AAPL)|((Apple,?.?(([iI]nc).?)?))|((technology|electronics){1,2})|(consumer electronics)|((timothy d. cook|thimothy cook))|((smart phones|computers|laptops){1,3})|((iphone|ipad|ipod|airpods|macbook){1,5})/g

和字符串:

"AAPL apple inc., apple, apple, inc., apple, inc technology, electronics consumer electronics timothy d. cook, thimothy cook smart phones, computers, laptops iphone, ipad, ipod, airpods, macbook"

RegExp.protype.match((的结果是一个包含大多数未定义项的数组:

[ "AAPL", "AAPL", undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined ]

但是,当我使用https://regexr.com/它匹配了我期望匹配的所有单词。

我也尝试过将上面的正则表达式包装在括号中,比如(string){1,100),但仍然得到了一个包含大部分未定义项的数组。

我对正则表达式有什么不理解的地方

下面是我的JS代码:

type SearchPatterns = {
[key: string]: {
[key: string]: RegExp;
}
};
const SEARCH_PATTERNS: SearchPatterns = {
AAPL:  {
symbol: /(AAPL)/, //"AAPL"
name: /((Apple,?.?(([iI]nc).?)?))/, //"apple inc.", "apple", "apple, inc.", "apple, inc"
sectors: /((technology|electronics){1,2})/, //"technology", "electronics"
industry: /(consumer electronics)/, //"consumer electronics"
executives: /((timothy d. cook|thimothy cook))/, //"timothy d. cook", "thimothy cook"
productCategories: /((smart phones|computers|laptops){1,3})/, //"smart phones", "computers", "laptops"
products: /((iphone|ipad|ipod|airpods|macbook){1,5})/ //"iphone", "ipad", "ipod", "airpods", "macbook"
}
};
function screenStockInfo(
symbol: string,
corpus: string,
searchPatterns
) {
const regStr = (Object.values(searchPatterns[symbol]) as RegExp[])
.map(value => value.source)
.join("|");
const dynamicRegEx = new RegExp(regStr, "g");
console.log(dynamicRegEx.exec(corpus));
console.log(dynamicRegEx);
return dynamicRegEx.test(corpus);
};

对于在结果中包含子组的方法(例如使用RegExp.testRegExp.execString.matchAll(,任何不匹配的捕获子组都由undefined值表示。这是因为每个子群都有编号,因此结果中每个子群的数字索引处都必须出现一些内容。如果忽略了不匹配的组,则匹配组的索引将与其组号不同。

对于任何不想被捕获的子组,请使用非捕获子组(如果只需要完全匹配,而不需要子组,则使用String.match(。如果您需要捕获一个子组,只需忽略任何丢失的值即可。您还可以使用命名组,这样可以产生更可读的结果,并且不那么脆弱(因为您不太可能使用错误的索引(。

String.matchString.matchAll不同,RegExp.testRegExp.exec每次都找到一个匹配项。您必须多次调用它们才能获得连续的匹配。这包含在MDN文档中:

当JavaScript RegExp对象设置了全局或粘性标志(例如/foo/g/foo/y(时,它们是有状态的。它们存储上一场比赛的lastIndex。在内部使用它,test()可以用于迭代文本字符串中的多个匹配(使用捕获组(。

JavaScript RegExp对象是*有状态的(当它们设置了全局或粘性标志(例如/foo/g/foo/y(时(。它们存储上一场比赛的lastIndex。在内部使用它,exec()可以用于迭代文本字符串中的多个匹配(使用捕获组(,而不是使用String.prototype.match()只获得匹配的字符串。

对于全局RegExp,String.match返回完全匹配,但不返回子组。请注意,MDN:的文档中包含了这一点

返回值

一个数组,其内容取决于全局(g(标志的存在与否,如果未找到匹配项,则为null。

  • 如果使用g标志,将返回所有与完整正则表达式匹配的结果,但不包括捕获组

String.matchAll类似于RegExp.exec,它迭代并返回连续的匹配,但它是作为生成器来执行的,因此您可以将结果扩展到一个数组中:

[...corpus.matchAll(dynamicRegEx)];

最新更新