google-apps-script - tutorial - google apps script語法




替換文字()正則表達式“後面沒有” (2)

任何想法為什麼這個簡單的正則表達式似乎不支持在谷歌文檔腳本?

富(?!欄)

我假設Google Apps Script使用與JavaScript相同的RegEx。 這不是嗎?

我正在使用RegEx:

DocumentApp.getActiveDocument().getBody().replaceText('foo(?!bar)', 'hello');

這會產生錯誤:

ScriptError:無效的正則表達式模式foo(?!bar)


正如在對這個問題的評論中所討論的那樣,這是一個記錄的限制 replaceText()方法不支持反向查找或任何其他捕獲組。

JavaScript正則表達式功能的子集不完全受支持,例如捕獲組和模式修飾符。 REF

Serge提出了一個解決方法,“應該可以在較低的層次上處理文檔(從段落中提取文本),但是它可能會很快變得非常麻煩。

這是可能的樣子。 如果您不介意丟失所有格式,則此示例將應用捕獲組,RegExp標誌( i為不區分大小寫)和反向超前更改:

小兔子Foo Foo ,穿過foob​​ar

至:

小兔子弗雷德弗雷德,穿過foobar。

碼:

function myFunction() {
  var body = DocumentApp.getActiveDocument().getBody();
  var paragraphs = body.getParagraphs();
  for (var i=0; i<paragraphs.length; i++) {
    var text = paragraphs[i].getText();
    paragraphs[i].replaceText(".*", text.replace(/(f)oo(?!bar)/gi, '$1red') );
  }
}

你有一個你可以用正則表達式匹配的序列,但是這個正則表達式也會匹配一個或者更多你不想改變的東西。 這種情況的一般化解決方案是:

  1. 改變文字,使你有已知的字符序列是絕對不使用。 實際上,這給你一系列字符,你可以用它們作為變量來保存你不想改變的值。 我個人會使用:
    body.replaceText('Q','Qz');
    這將使得你的文檔中沒有任何匹配/Q[^z]/序列。 這導致您可以使用像Qa這樣的序列來表示一些您不想更改的文本。 我使用Q因為它的英文使用頻率很低。 你可以使用任何字符。 為了提高效率,請選擇一個字符,以便在您正在影響的文本內產生少量的更改。
  2. 改變你不想變成你現在知道不用的字符序列之一。 例如:
    body.replaceText('foobar','Qa');
    對任何你不想改變的東西重複這個。
  3. 改變你真的想改變的文字。 在這個例子中: body.replaceText('foo','hello'.replace(/Q/g,'Qz'));
    請注意,您需要將新的替換文本應用於打開已知未使用序列的第一個替換。
  4. 還原所有不想更改為原始狀態的內容:
    body.replaceText('Qa','foobar');
  5. 恢復用來打開未使用的字符序列的文本:
    body.replaceText('Qz','Q');

所有這一切將是:

var body = DocumentApp.getActiveDocument().getBody();
body.replaceText('Q','Qz');      //Open up unused character sequences
body.replaceText('foobar','Qa'); //Save the things you don't want to change.

//In the general case, you need to apply to the new text the same substitution
//  which you used to open up unused character sequences.  If you don't you
//  may end up with those sequences being changed in the new text.
body.replaceText('foo','hello'.replace(/Q/g,'Qz')); //Make the change you desire.

body.replaceText('Qa','foobar'); //Restore the things you saved.
body.replaceText('Qz','Q');      //Restore the original sequence.

以這種方式解決問題時,不允許使用JavaScript RegExp的所有功能(例如捕獲組,預讀斷言和標誌),它應該保留文檔中的格式。

您可以選擇不執行上述步驟1和5,方法是選取較長的字符序列來表示不想匹配的文本(例如kNoWn1UnUsEd )。 然而,這樣一個更長的序列是必鬚根據你對文件中已經存在的知識來選擇的。 這樣做可以節省幾個步驟,但是您必須搜索未使用的字符串,或者接受使用的字符串已經存在於文檔中的可能性,否則會導致不必要的替換。