Google表格从列表中进行多次搜索和替换

Chr*_*oph 5 search replace google-sheets

我正在寻找一种搜索Google表格中某些字符串的解决方案,一旦找到,就用另一张表格中的另一个字符串替换它们.

为了更好地理解,我为您准备了一张表:

https://docs.google.com/a/vicampo.de/spreadsheets/d/1mETtAY72K6ST-hg1qOU9651265nGq0qvcgvzMRqHDO8/edit?usp=sharing

所以这是我想要实现的确切任务:

在"文本"工作表的A列中的每个单元格中,查找工作表"列表"中A列中给出的字符串,找到后,将其替换为工作表"列表"的B列中的相应字符串.

请参阅我的示例:在单元格A1中查找字符串"Lorem"并将其替换为"Xlorem",然后查找字符串"Ipsum"并将其替换为"Xipsum",然后查找字符串"amet"并将其替换为然后"Xamet"转到单元格B1并再次开始查找字符串......

我尝试了不同的功能,并设法用一个单元格的功能.但是如何在循环中做到这一点?

感谢所有有兴趣帮助解决这个问题的人!

JPV*_*JPV 10

尽管必须有“更好”的解决方案,但一个快速的解决方案(只要您要替换的单词的单元格数量不会太长),将是:

=ArrayFormula(regexreplace(regexreplace(regexreplace(A1:A; List!A1; List!B1); List!A2; List!B2); List!A3; List!B3))
Run Code Online (Sandbox Code Playgroud)

  • 事实证明,“SUBSTITUTE”对于这项任务来说更快、更安全。我添加了我自己的答案。 (2认同)

Max*_*rov 8

复制带有说明的示例文件

\n

在此输入图像描述

\n

问题

\n

在此输入图像描述

\n

挑战是:\n查找并替换多个单元格输入中的多个值。

\n

数组公式

\n

我将其视为数组解决方案的解决方案必须是:

\n
    \n
  1. 基于开区间
  2. \n
  3. 无需向下拖动公式
  4. \n
  5. 当列表中出现新项目时,无需修改公式
  6. \n
\n

必须通过这些测试:

\n
    \n
  • 是数组公式
  • \n
  • 用户可以设置区分大小写
  • \n
  • 取代表情符号
  • \n
  • 替换特殊字符 $\\[].等。
  • \n
  • 碰撞测试。适用于 10K 行数据
  • \n
  • 碰撞测试。适用于 2K 替换件
  • \n
\n

脚本

\n

在这种情况下,我建议使用不基于正则表达式的脚本。该算法查找文本并用字符替换文本:

\n

用法

\n

用作工作表中的常规公式:

\n

=substitutes(A12:A;List!A1:B)

\n

在此输入图像描述

\n

代码

\n

保存此代码以使用上面的公式:

\n
/**\n * Substitutes in every entry in array\n * Text from prefilled array\n *\n * @param {array} input The array of strings.\n * @param {array} subTable The array of string pairs: search texts / replace texts.\n * @param {boolean} caseSensitive [optional=false] \n * TRUE to match Apple and apple as different words\n * @return The input with all replacement made\n * @customfunction\n */\nfunction substitutes(input, subTable,caseSensitive) {\n  //  default behavior it is not case sensitive\n  caseSensitive = caseSensitive || false;\n  // if the input is not a list, become a list */\n  if( typeof input != "object" ) {\n    input = [ input ];\n  }\n  var res = [], text;\n  for (var i = 0; i < input.length; i++) {\n    // force each array element in the input be a string\n    text = input[i].toString();\n    for (var ii = 0; ii < subTable.length; ii++) {\n      text = replaceAll_(\n        text, \n        subTable[ii][0], \n        subTable[ii][1], \n        caseSensitive);\n    }\n    res.push(text);\n  }\n  return res;\n}\n\n\n/***\n * JavaScript Non-regex Replace\n * \n * Original code sourse:\n * /sf/answers/3989275321/\n */\nfunction replaceAll_(str, find, newToken, caseSensitive) {\n    var i = -1;\n    // sanity check & defaults\n    if (!str) {\n        // Instead of throwing, act as \n        // COALESCE if find == null/empty and str == null\n        if ((str == null) && (find == null))\n            return newToken;\n        return str;\n    }\n    if (!find || find === \'\'){ return str; }\n    if (find === newToken) { return str; }\n    caseSensitive = caseSensitive || false;\n    find = !caseSensitive ? find.toLowerCase() : find;\n    // search process, search by char\n    while ((\n        i = (!caseSensitive ? str.toLowerCase() : str).indexOf(\n            find, i >= 0 ? i + newToken.length : 0\n        )) !== -1\n    ) {\n        str = str.substring(0, i) +\n            newToken +\n            str.substring(i + find.length);\n    } \n    return str;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

怪物方程式

\n

我已经使用 RegEx 算法通过本机函数来解决它。不建议使用此方法,因为它会减慢工作表的速度。

\n

公式为:

\n
=INDEX(SUBSTITUTE(REGEXREPLACE(TRANSPOSE(QUERY(TRANSPOSE(IFERROR(SPLIT(SUBSTITUTE(TRANSPOSE(QUERY(TRANSPOSE(IFERROR(VLOOKUP(SPLIT(REGEXREPLACE(A12:A;SUBSTITUTE(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1");"";"(.*)");INDEX(REGEXREPLACE(TRIM(TRANSPOSE(QUERY(TRANSPOSE(IF(SEQUENCE(COUNTA(INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2));MAX(INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2)))-(SEQUENCE(COUNTA(INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2)))-1)*MAX(INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2))<=INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2);""&SEQUENCE(COUNTA(INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2));MAX(INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2)))-(SEQUENCE(COUNTA(INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2)))-1)*MAX(INDEX(LEN(REGEXREPLACE(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"");"[^]";""))/2))&"";));;2^99)));" ?";"$")));"");{List!A1:A\\List!B1:B};2;)&""));;2^99));" ";"")&"";"")&SPLIT(REGEXREPLACE(A12:A;"(?i)"&SUBSTITUTE(SUBSTITUTE(QUERY(FILTER(REGEXREPLACE(List!A1:A;"(\\\\|\\+|\\*|\\?|\\[|\\^|\\]|\\$|\\(|\\)|\\{|\\}|\\=|\\!|\\<|\\>|\\||\\:|\\-)";"\\\\$1")&"";List!A1:A<>"");;2^99);" ";"|");"";"");"")&"";"")))&"";;2^99));" *";"");"";""))\n
Run Code Online (Sandbox Code Playgroud)\n

其他解决方案

\n

嵌套公式

\n

嵌套SUBSTITUTE或REGEXREPLACE公式如其他答案中所述。

\n

您需要向下拖动以获得结果的公式

\n

这是一个示例公式。基本逻辑 - 将文本拆分为多个部分 \xe2\x86\x92 单独修改部分 \xe2\x86\x92 以加入新结果。

\n

这个公式必须抄下来:

\n
=JOIN(" ";\nArrayFormula(\nIFERROR(VLOOKUP(TRANSPOSE(SPLIT(A1;" "));List!A:B;2;0);TRANSPOSE(SPLIT(A1;" ")))))\n
Run Code Online (Sandbox Code Playgroud)\n

  • 这是如此彻底详细的答案,应该接受并给予更多支持!该脚本非常适合我! (2认同)

Thi*_*ata 6

在这种情况下,对您来说最好的方法可能是为您的 Google 电子表格创建一个新函数。在一般情况下,它往往比应该做同样事情的那种复杂的公式更简单、清晰和强大。

在这种特殊情况下,我遇到了同样的问题,因此您可以使用相同的功能:

单击“工具”菜单,然后单击“脚本编辑器”选项。进入脚本编辑器,擦除草稿并粘贴此功能:

function preg_quote( str ) {
  // http://kevin.vanzonneveld.net
  // +   original by: booeyOH
  // +   improved by: Ates Goral (http://magnetiq.com)
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +   bugfixed by: Onno Marsman
  // *     example 1: preg_quote("$40");
  // *     returns 1: '\$40'
  // *     example 2: preg_quote("*RRRING* Hello?");
  // *     returns 2: '\*RRRING\* Hello\?'
  // *     example 3: preg_quote("\\.+*?[^]$(){}=!<>|:");
  // *     returns 3: '\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:'

  return (str+'').replace(/([\\\.\+\*\?\[\^\]\$\(\)\{\}\=\!\<\>\|\:])/g, "\\$1");
}

function ARRAYREPLACE(input,fromList,toList,caseSensitive){
  /* default behavior it is not case sensitive */
  if( caseSensitive === undefined ){
    caseSensitive = false;
  }
  /* if the from list it is not a list, become a list */
  if( typeof fromList != "object" ) {
    fromList = [ fromList ];
  }
  /* if the to list it is not a list, become a list */
  if( typeof toList != "object" ) {
    toList = [ toList ];
  }
  /* force the input be a string */
  var result = input.toString();

  /* iterates using the max size */
  var bigger  = Math.max( fromList.length, toList.length) ;

  /* defines the words separators */
  var arrWordSeparator = [ ".", ",", ";", " " ];

  /* interate into the lists */
  for(var i = 0; i < bigger; i++ ) {
    /* get the word that should be replaced */
    var fromValue = fromList[ ( i % ( fromList.length ) ) ]
    /* get the new word that should replace */
    var toValue = toList[ ( i % ( toList.length ) ) ]

    /* do not replace undefined */
    if ( fromValue === undefined ) {
      continue;
    }
    if ( toValue == undefined ) {
      toValue = "";
    }

    /* apply case sensitive rule */
    var caseRule = "g";
    if( !caseSensitive ) {
      /* make the regex case insensitive */
      caseRule = "gi";
    }

    /* for each end word char, make the replacement and update the result */
    for ( var j = 0; j < arrWordSeparator.length; j++ ) {
      
      /* from value being the first word of the string */
      result =  result.replace( new RegExp( "^(" + preg_quote( fromValue + arrWordSeparator[ j ] ) + ")" , caseRule ), toValue + arrWordSeparator[ j ] );
      
      /* from value being the last word of the string */
      result =  result.replace( new RegExp( "(" + preg_quote( arrWordSeparator[ j ] + fromValue ) + ")$" , caseRule ), arrWordSeparator[ j ] + toValue );
      
      /* from value in the middle of the string between two word separators */
      for ( var k = 0; k < arrWordSeparator.length; k++ ) {
        result =  result.replace( 
          new RegExp( 
            "(" + preg_quote( arrWordSeparator[ j ] + fromValue + arrWordSeparator[ k ] ) + ")" , 
            caseRule 
          ), 
          /* need to keep the same word separators */
          arrWordSeparator[ j ] + toValue + arrWordSeparator[ k ] 
        );
      }
    }
    
    /* from value it is the only thing in the string */
    result =  result.replace( new RegExp( "^(" + preg_quote( fromValue ) + ")$" , caseRule ), toValue );
  }
  /* return the new result */
  return result;
}
Run Code Online (Sandbox Code Playgroud)

只需保存您的脚本,您就可以使用它的新功能。现在,您拥有将所有第一个值列表替换为第二个值列表的函数。

=ARRAYREPLACE(C2;A1:A4;B1:B4)
Run Code Online (Sandbox Code Playgroud)

例如,获取C2文本并将A1:A4列表中找到的所有元素替换为列表中的等效元素B1:B4。

将函数导入谷歌电子表格的使用示例


Arc*_*gon 5

对 JPV 答案的改进,速度快了几个数量级,并且适用于任意查询和替换字符串:

=ArrayFormula(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1:A, List!A1, List!B1), List!A2, List!B2), List!A3, List!B3))
Run Code Online (Sandbox Code Playgroud)

使用这种格式,包含 15,000 个单元格的电子表格以及 85 长度的替换列表将在几秒钟内更新。只需使用您选择的脚本语言组装公式字符串即可开始!


Max*_*rov 5

与新的 Labmda 和朋友们:

\n

=LAMBDA(data,re,with,BYROW(data,LAMBDA(r,if(r="","",REDUCE(r,SEQUENCE(counta(re)),LAMBDA(ini,v,REGEXREPLACE(ini,INDEX(re,v),INDEX(with,v))))))))(C5:C6,E5:E7,F5:F7)

\n

=> 命名函数

\n

=SUBSTITUTES_RE(list0,list_re,list_with)

\n

\xe2\x86\x91 这将使用正则表达式替换

\n
\n

substututes

\n

定义相同,但REGEXREPLACE替换为SUBSTITUTE

\n
\n

其他示例如下:\n https://docs.google.com/spreadsheets/d/1IMymPZlibT6DX4yzDX4OXj2XBZ48zEl6vBUzIHJIzVE/edit#gid=0

\n

在此输入图像描述

\n
\n

在此输入图像描述

\n
\n

在此输入图像描述

\n