2010-07-30 7 views
1

Existe-t-il un moyen de modifier la valeur d'une référence arrière?RegEx modifier la valeur de référence arrière

Exemple: Dans le texte suivant

"this is a test" 

le mot 'test' doit être extrait et inséré dans un autre texte via backrefrence.

Regex:

(test) 

remplacement:

"this is another \1" 

Cela fonctionne très bien jusqu'à présent. Mais maintenant, la question est, s'il est possible de modifier la référence arrière avant d'insérer. Quelque chose comme la conversion du mot "test" en majuscule.

Je pense qu'il pourrait ressembler à:

"this is another \to_upper\1" 

Y at-il quelque chose que défini dans la « norme » (il est une norme du tout?) Des expressions régulières?

+2

standard très probablement pas, mais vous pouvez le faire dans certaines implémentations: '$ echo testx | perl -pe 's/(test)/\ U \ 1 /' '->' TESTx' – mykhal

+2

De nombreuses implémentations (javascript, python etc.) vous permettent de spécifier une fonction comme paramètre de remplacement - la fonction prend normalement la chaîne correspondante et la capture groupes comme arguments et sa valeur de retour est utilisée comme texte de remplacement. – Amarghosh

+0

@Amarghosh: vous pourriez tout aussi bien poster comme réponse, et ajouter quelques exemples de code pendant que vous y êtes. –

Répondre

4

De nombreuses implémentations (javascript, python, etc.) vous permettent de spécifier une fonction en tant que paramètre de remplacement. La fonction prend normalement toute la chaîne correspondante, sa position dans la chaîne d'entrée et les groupes capturés comme arguments. La chaîne renvoyée par cette fonction est utilisée comme texte de remplacement.

Voici comment le faire en utilisant JavaScript: la fonction replace prend comme premier argument la sous-chaîne correspondante, la valeur des groupes capturés comme n prochains arguments, suivie de l'index de la chaîne correspondante dans la chaîne d'entrée originale toute la chaîne d'entrée.

var s = "this is a test. and this is another one."; 
console.log("replacing"); 
r = s.replace(/(this is) ([^.]+)/g, function(match, first, second, pos, input) { 
    console.log("matched :" + match); 
    console.log("1st group :" + first); 
    console.log("2nd group :" + second); 
    console.log("position :" + pos); 
    console.log("input  :" + input); 
    return "That is " + second.toUpperCase(); 
}); 
console.log("replaced string is"); 
console.log(r); 

ouput:

replacing 
matched :this is a test 
1st group :this is 
2nd group :a test 
pos  :0 
input  :this is a test. and this is another one. 
matched :this is another one 
1st group :this is 
2nd group :another one 
pos  :20 
input  :this is a test. and this is another one. 
replaced string is 
That is A TEST. and That is ANOTHER ONE. 

Et voici la version python - il vous donne même démarrer/valeurs de fin pour chaque groupe:

#!/usr/bin/python 
import re 
s = "this is a test. and this is another one."; 
print("replacing"); 

def repl(match): 
    print "matched :%s" %(match.string[match.start():match.end()]) 
    print "1st group :%s" %(match.group(1)) 
    print "2nd group :%s" %(match.group(2)) 
    print "position :%d %d %d" %(match.start(), match.start(1), match.start(2)) 
    print "input  :%s" %(match.string) 
    return "That is %s" %(match.group(2).upper()) 

print "replaced string is \n%s"%(re.sub(r"(this is) ([^.]+)", repl, s)) 

Sortie:

replacing 
matched :this is a test 
1st group :this is 
2nd group :a test 
position :0 0 8 
input  :this is a test. and this is another one. 
matched :this is another one 
1st group :this is 
2nd group :another one 
position :20 20 28 
input  :this is a test. and this is another one. 
replaced string is 
That is A TEST. and That is ANOTHER ONE. 
Questions connexes