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

时间:2015-04-02 10:50:45

标签: 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并再次开始查找字符串......

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

感谢所有有兴趣帮助解决此问题的人

5 个答案:

答案 0 :(得分:4)

虽然必须有“更好”的解决方案,但是快速的解决方案(只要你想要替换的单词的数量不会太长),就会:

=ArrayFormula(regexreplace(regexreplace(regexreplace(A1:A; List!A1; List!B1); List!A2; List!B2); List!A3; List!B3))

答案 1 :(得分:0)

必须复制此公式:

=JOIN(" ";
ArrayFormula(
IFERROR(VLOOKUP(TRANSPOSE(SPLIT(A1;" "));List!A:B;2;0);TRANSPOSE(SPLIT(A1;" ")))))

缺点是它与标点符号不匹配,因此将找到单词'Lorem',但'Lorem:'不会。但是使用这种方法的充分理由是你可以填写清单2中的更多单词,甚至粘贴'Lorem:'以便它也可以匹配。

答案 2 :(得分:0)

在这种情况下,对你来说最好的方法应该是为你的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;
}

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

=ARRAYREPLACE(C2,A1:A4,B1:B4)
例如,

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

example of the use of the function into Google Spreadsheet

答案 3 :(得分:0)

对JPV的回答有所改进,它的速度提高了几个数量级,可以处理任意查询和替换字符串:

=ArrayFormula(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A1:A, List!A1, List!B1), List!A2, List!B2), List!A3, List!B3))

使用此格式,只需几秒钟即可更新一个包含85长度替换列表的15,000个单元格电子表格。只需使用您选择的脚本语言组装公式字符串,您就可以了!

答案 4 :(得分:0)

这里的脚本比 Thiago Mata 的要简单一些。我从 https://webapps.stackexchange.com/a/46895 修改了脚本以支持单个单元格或范围输入

function MSUBSTITUTE(input, subTable)
{
  var searchArray = [], subArray = [], outputArray = [];
  for (var i = 0, length = subTable.length; i < length; i++)
  {
    if (subTable[i][0])
    {
      searchArray.push(subTable[i][0]);
      subArray.push(subTable[i][1]);
    }
  }
  var re = new RegExp(searchArray.join('|'), 'g');
  
  /* Check if we got just a single string */
  if (typeof( input ) == "string")
  {
    outputArray.push(input.replace(re, function (match) {return subArray[searchArray.indexOf(match)];}));
  } 
  else /* we got an array of strings */
  {
    for (var i = 0; i < input.length; i++)
    {
      /* force each array element in the input be a string */
      var text = input[i].toString();
      outputArray.push(text.replace(re, function (match) {return subArray[searchArray.indexOf(match)];}))
    }
  }
  return outputArray;
}