将字符串中的所有子项与正则表达式匹配为不同的匹配项

问题描述 投票:0回答:1

我有一个字符串,需要最终得到一个对象来计算每个名字的所有苹果,我的努力是为他们拿走的每个苹果获得单独的匹配

在 <@Viktor><@Kate>took:apple::apple: 部分中,我想要获得两个匹配项而不是 1 个,如果有更多像 <@Viktor><@Kate>took:apple::apple::apple::apple:

这样的苹果,则需要更多匹配项
const message = 'I had :apple::apple::apple::apple: :apple:<@Viktor><@Kate>took:apple::apple: and later <@viktor> took again:apple:but not <@kate>';

const result {
     viktor: 3,
     kate: 2
}

用这个来处理问题,但是没有被面试官接受,因为我后来使用了join&split。任务是仅使用正则表达式来解决这个问题。

function countGifts(text) {
    let result = {}
    let names = ['viktor', 'kate']
    names.forEach(name=>{
        let regex =  new RegExp(`(${name}).*?(:apple:)+`, "gi")
        result[name] = text.match(regex).join('').split(':apple:').length-1
    })
    return result
}
console.log(
    countGifts(message)
);

我是正则表达式的新手,并且希望获得具有复杂示例的文章的替代解决方案和提示,因为我发现的所有内容都非常简单

javascript regex string algorithm match
1个回答
0
投票

我假设如果多个名称标签彼此后面可能带有一些分隔文本,但不是

:apple:
,那么它们都会得到后面的苹果。我还将假设,如果名称标签在此类列表中重复,则重复项将被忽略。所以
<@Victor><@Victor> :apple:
会将一个苹果分配给 Victor,而不是两个。

这是一种方法:

function countGifts(text) {
    const result = {};
    let isCollecting = false;
    const names = new Set; // Those that will get apples
    for (const [_, name] of text.matchAll(/:apple:|<@(\w+)>/g)) {
        if (name === undefined) { // Add apple
            isCollecting = false;
            for (const key of names) {
                result[key] = (result[key] || 0) + 1;
            }
        } else {
            if (!isCollecting) names.clear();
            isCollecting = true;
            names.add(name.toLowerCase());
        }
    }
    return result;
}

const message = 'I had :apple::apple::apple::apple: :apple:<@Viktor><@Kate>took:apple::apple: and later <@viktor> took again:apple:but not <@kate>';

const result = countGifts(message);
console.log(result);

© www.soinside.com 2019 - 2024. All rights reserved.