gpt4 book ai didi

JavaScript 在正确的出现处映射具有多个匹配项的正则表达式

转载 作者:行者123 更新时间:2023-11-30 11:11:36 30 4
gpt4 key购买 nike

我有一个 array 要映射的标记,以及一个获取输入句子中每个标记的开始和结束位置的正则表达式。当 token 出现一次时,这可以正常工作。当标记多次出现时,贪婪的 Regex 将获取标记在文本中的所有匹配位置,因此第 i 个标记出现的结果位置将映射到最后找到的位置。

例如,给定文本

var text = "Steve down walks warily down the street down\nWith the brim pulled way down low";

标记 down 的第一次出现被映射到与 RegExp 匹配的文本中的最后一个位置,因此我有:

 {
"index": 2,
"word": "down",
"characterOffsetBegin": 70,
"characterOffsetEnd": 73
}

运行这个例子就很清楚了:

var text = "Steve down walks warily down the street down\nWith the brim pulled way down low";
var tokens = text.split(/\s+/g);
var annotations = tokens.map((word, tokenIndex) => { // for each token
let item = {
"index": (tokenIndex + 1),
"word": word
}
var wordRegex = RegExp("\\b(" + word + ")\\b", "g");
var match = null;
while ((match = wordRegex.exec(text)) !== null) {
var wordStart = match.index;
var wordEnd = wordStart + word.length - 1;
item.characterOffsetBegin = wordStart;
item.characterOffsetEnd = wordEnd;
}
return item;
});
console.log(annotations)

标记 down 的第一次出现应该是第一个匹配位置:

 {
"index": 2,
"word": "down",
"characterOffsetBegin": 6,
"characterOffsetEnd": 9
}

鉴于我已经为文本中每次出现的标记映射了标记位置,即第一次出现 down 与第一个匹配项,第二个与第二个匹配项等。我可以重建与 charOffsetBegincharOffsetEnd 相应的文本因此这样做:

                var newtext = '';
results.sentences.forEach(sentence => {
sentence.tokens.forEach(token => {
newtext += text.substring(token.characterOffsetBegin, token.characterOffsetEnd + 1) + ' ';
});
newtext += '\n';
});

最佳答案

问题不在于表达式是贪婪的,而是您正在使用 while 循环寻找输入字符串中标记的匹配项。

你必须做两件事:

  • 找到匹配项后停止迭代。
  • 跟踪以前的比赛,以便您可以忽略它们。

我相信这就是你想要的:

var text = "Steve down walks warily down the street down\nWith the brim pulled way down low";
var tokens = text.split(/\s+/g);
const seen = new Map();

var annotations = tokens.map((word, tokenIndex) => { // for each token
let item = {
"index": (tokenIndex + 1),
"word": word
}
var wordRegex = RegExp("\\b(" + word + ")\\b", "g");
var match = null;
while ((match = wordRegex.exec(text)) !== null) {
if (match.index > (seen.get(word) || -1)) {
var wordStart = match.index;
var wordEnd = wordStart + word.length - 1;
item.characterOffsetBegin = wordStart;
item.characterOffsetEnd = wordEnd;

seen.set(word, wordEnd);
break;
}
}
return item;
});
console.log(annotations)

seen map 跟踪标记的最近匹配的结束位置。

因为不可能告诉正则表达式引擎忽略特定位置之前的所有内容,我们仍然使用 while 循环,但是忽略了上一次匹配之前发生的任何匹配, if (match.index > (seen.get(word) || -1)).

关于JavaScript 在正确的出现处映射具有多个匹配项的正则表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53403314/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com