我有两个 Google 表格。我想找到表 1 的第一个单元格(包含通配符)与表 2 中的值匹配。然后,将匹配表达式单元格下一列中的值放入表 2 的第二列。
例如下表:
这里是CSV数据:
Job Wildcards,Salary,,Job Description,Salary
*Dev*,40000,,Junior Developer,40000
*Engineer*,50000,,Senior Developer,40000
*Manager*,60000,,Platform Engineer,50000
,,,Project Manager,60000
,,,Team Manager,60000
E 列中的工资应通过在第一个表中查找与“职位描述”匹配的第一个“工作通配符”并保存其工资来自动填充。我手动提供了正确的值。
首先我想到了
vlookup
:
=VLOOKUP(D2,A$2:$B5,2,FALSE)
但是错误消息确认这不起作用:
Did not find value 'Junior Developer' in VLOOKUP evaluation.
。因为我不想找到“初级开发人员”,所以我想知道反过来匹配什么。
然后我尝试像这样使用索引和匹配:
=INDEX(B$2:B$6,MATCH(D2,A$2:A$7,0))
但是这会返回一个
#N/A
与 vlookup
有点相同的错误: Did not find value 'Junior Developer' in MATCH evaluation.
这又是有道理的。我仍然需要将 A 列与 D 进行匹配,而不是将 D 与 A 进行匹配。但是我该怎么做呢?
然后我尝试使用
REGEXMATCH
。为此,我将通配符更改为正则表达式(将 *
更改为 .*
):
=INDEX(FILTER(REGEXMATCH(A2,ARRAYFORMULA(D2:D7)), NOT(FALSE)), 1)
但是在这里,我得到了错误
FILTER has mismatched range sizes. Expected row count: 7. column count: 1. Actual row count: 1, column count: 1.
。而在这一点上,我就此认输了
我也用
*
替换了%
并尝试了QUERY
:
=QUERY($A$2:$D$6,"SELECT B where D like A")
但这也没有达到我希望的效果
我想我很接近,但我真的很感激向正确的方向轻推。
你可以试试:
使用
Xmatch
=map(D2:D,lambda(Σ,if(Σ="",,
array_constrain(torow(reduce(,sequence(counta(A2:A)),lambda(a,c,{a;if(ifna(xmatch(index(A2:A,c),Σ,2)),index(B2:B,c),)})),1),1,1))))
这是不区分大小写;
*Dev*
同时匹配 Junior Developer
和 Redevelopment
使用
Find
=map(D2:D,lambda(Σ,if(Σ="",,
array_constrain(torow(reduce(,sequence(counta(A2:A)),lambda(a,c,{a;if(iferror(find(index(substitute(A2:A,"*",""),c),Σ)),index(B2:B,c),)})),1),1,1))))
这是区分大小写;
*Dev*
仅匹配 Junior Developer
而不是 Redevelopment
这是另一个解决方案:
=ARRAYFORMULA(
BYROW(
IF(ISERR(FIND(TOROW(SPLIT(A2:A,"*"),1),TOCOL(D2:D,1))),,
TOROW(B2:B,1)),
LAMBDA(x,IFNA(INDEX(x,XMATCH(,--(x="")))))))
这是区分大小写的,如果您不希望它区分大小写,请将
FIND
替换为SEARCH
。
@ztiaa 和@rockinfreakshow 的解决方案大约有 5-20% 的时间是不正确的,具体取决于正则表达式列排序。由于这些公式非常复杂,我不知道如何调试它们。
我找到了另外两个解决方案。
转到 Extensions->Apps Script 并添加以下自定义函数:
/**
* Find the first cell of a range that matches against the given text and return a return value.
* @param {string} input The text to search for.
* @param {range} input Two colums. The first must contain regular expressions to match against. The second must contain the corresponding return values.
* @return The return value of the first regex match in the range that matches the given text. Returns 'NO_MATCH' on no match.
* @customfunction
*/
function matchTextToRegexArray(cellText, regexResultsArray) {
for (var i = 0; i < regexResultsArray.length; i++) {
var regex = new RegExp(regexResultsArray[i][0], "i");
if (regex.test(cellText)) {
return regexResultsArray[i][1];
}
}
return "NO_MATCH";
}
在表格中用作
=matchTextToRegexArray(D2,A$2:B)
.
这个,对我来说,很容易理解。但它可能会很慢。解决方案 2
更快我找到了正确的查询:
=QUERY(A$3:$B$99, "select B where '"&lower(D2)&"' matches LOWER(A) limit 1")
地点:
.*
在此列中所有术语的开头和结尾)这快速、简单,不需要任何额外的东西。
永远感谢!