2017-02-18 5 views
0

Supposons que nous avons dans notre premier paragraphe google document:Google Apps Script: remplacer partielle docs ce qui correspond seulement et préserver le formatage

Wo1rd mot so2me mot he3re dernier.

Nous devons search and replace certaines parties du texte, mais il faut souligner dans éditions histoire juste comme nous avons changé seulement que les pièces et nous ne devons pas perdre notre format (gras, italique, couleur etc). Ce que j'ai compris pour ce moment: capturing groups ne fonctionnait pas dans replaceText() comme décrit dans la documentation. Nous pouvons utiliser pure js replace(), mais il ne peut être utilisé que pour les chaînes. Notre document google est un tableau d'objets, pas de chaînes. J'ai donc fait beaucoup d'essais et arrêté à ce code, joint dans ce message plus tard.

Impossible de battre: comment je peux remplacer seulement une partie de ce que j'ai trouvé. Capturer des groupes est un instrument très puissant et approprié, mais je ne peux pas l'utiliser pour le remplacer. Ils n'ont pas fonctionné ou je peux remplacer le paragraphe entier, ce qui est inacceptable en raison de l'histoire des éditions montrera le paragraphe complet remplacer et les paragraphes perdront le formatage. Et si ce que nous cherchons sera dans chaque paragraphe, mais qu'une seule lettre doit être changée? Nous verrons le remplacement complet des documents dans l'histoire et il sera difficile de trouver ce qui a vraiment changé. Ma première idée a été de comparer les chaînes, que me remplace() me donne avec le contenu du paragraphe puis compare symbole après symbole et remplace ce qui est différent, mais je comprends, ça ne marchera que si on est sûr qu'un seul lettre changée. Mais que faire si remplacer va supprimer/ajouter quelques mots, comment il peut être synchronisé? Ce sera un problème beaucoup plus gros.

Tous les sujets que j'ai trouvé et lu trois fois n'ont pas aidé et ne m'a pas déplacé du point mort.

Alors, y a-t-il des idées pour vaincre ce problème?

function RegExp_test() { 
    var docParagraphs = DocumentApp.getActiveDocument().getBody().getParagraphs(); 
    var i = 0, text0, text1, test1, re, rt, count; 

    // equivalent of .asText() ??? 
    text0 = docParagraphs[i].editAsText(); // obj 
    // equivalent of .editAsText().getText(), .asText().getText() 
    text1 = docParagraphs[i].getText();  // str 

    if (text1 !== '') { 
    re = new RegExp(/(?:([Ww]o)\d(rd))|(?:([Ss]o)\d(me))|(?:([Hh]e)\d(re))/g); // v1 
// re = new RegExp(/(?:([Ww]o)\d(rd))/);   // v2 

    count = (text1.match(re) || []).length;  // re v1: 7, re v2: 3 

    if (count) { 
     test1 = text1.match(re); // v1: ["Wo1rd", "Wo", "rd", , , , , ] 
//  for (var j = 0; j < count; j++) { 
//  test1 = text1.match(re)[j]; 
//  } 

     text0.replaceText("(?:([Ww]o)\\d(rd))", '\1-A-\2'); // GAS func 
     // #1: \1, \2 etc - didn't work: " -A- word so2me word he3re last." 
     test1 = text0.getText(); 

     // js func, text2 OK: "Wo1rd word so-B-me word he3re last.", just in memory now 
     text1 = text1.replace(/(?:([Ss]o)\d(me))/, '$1-B-$2'); // working with str, not obj 
     // rt OK: "Wo1rd word so-B-me word he-C-re last." 
     rt = text1.replace(/(?:([Hh]e)\d(re))/, '$1-C-$2'); 

     // #2: we used capturing groups ok, but replaced whole line and lost all formatting 
     text0.replaceText(".*", rt); 
     test1 = text0.getText(); 
    } 
    } 
    Logger.log('Test finished') 
} 

Répondre

0

Trouvé une solution. C'est assez primitif mais cela peut être une base pour une procédure plus complexe qui peut réparer toutes les occurrences de groupes de capture, les détecter, les mélanger, etc. Si quelqu'un veut améliorer cela, vous êtes les bienvenus!

function replaceTextCG(text0, re, to) { 
    var res, pos_f, pos_l; 
    var matches = text0.getText().match(re); 
    var count = (matches || []).length; 

    to = to.replace(/(\$\d+)/g, ',$1,').replace(/^,/, '').replace(/,$/, '').split(","); 
    for (var i = 0; i < count; i++) { 
    res = re.exec(text0.getText()) 
    for (var j = 1; j < res.length - 1; j++) { 
     pos_f = res.index + res[j].length; 
     pos_l = re.lastIndex - res[j + 1].length - 1; 
     text0.deleteText(pos_f, pos_l); 
     text0.insertText(pos_f, to[1]); 
    } 
    } 
    return count; 
} 

function RegExp_test() { 
    var docParagraphs = DocumentApp.getActiveDocument().getBody().getParagraphs(); 
    var i = 0, text0, count; 

    // equivalent of .asText() ??? 
    text0 = docParagraphs[i].editAsText(); // obj 
    if (text0.getText() !== '') { 
    count = replaceTextCG(text0, /(?:([Ww]o)\d(rd))/g, '$1A$2'); 
    count = replaceTextCG(text0, /(?:([Ss]o)\d(me))/g, '$1B$2'); 
    count = replaceTextCG(text0, /(?:([Hh]e)\d(re))/g, '$1C$2'); 
    } 
    Logger.log('Test finished') 
}