2009-08-12 8 views
0

J'ai du mal à trouver une solution à cela et je suis assez sûr que regex le supporte. Je ne peux pas me rappeler le nom du concept dans le monde de regex.Regex rechercher et remplacer où le remplacement est un mod du terme de recherche

J'ai besoin de rechercher et de remplacer une chaîne pour un modèle spécifique, mais les modèles peuvent être différents et le remplacement doit «se souvenir» de ce qu'il remplace.

Par exemple, dire que j'ai une chaîne arbitraire: 134kshflskj9809hkj

et je veux entourer les chiffres avec des parenthèses, de sorte que le résultat serait: (134) kshflskj (9809) hkj

numéros de Trouver est assez simple, mais comment les entourer? Est-ce que n'importe qui peut fournir un échantillon ou me pointer dans la bonne direction?

+3

Dans quelle langue travaillez-vous? Le concept est appelé backreference btw: http://www.regular-expressions.info/brackets.html – gnarf

+0

C# spécifiquement, mais a quitté ce fait délibérément. Je suis curieux de savoir comment faire avec regex "général". Merci pour le jog de mémoire de référence arrière. C'est vrai. –

+2

Regex n'est pas agnostique. Pour l'implémentation de Perl et .NET de chaînes de remplacement d'expression régulière, c'est $ 1 pour le premier groupe, $ 2 pour le second, etc. Mais ce schéma n'est pas une règle absolue entre toutes les implémentations. –

Répondre

2

Dans certains langauges divers:

// C#: 
string result = Regex.Replace(input, @"(\d+)", "($1)"); 
// JavaScript: 
thestring.replace(/(\d+)/g, '($1)'); 
// Perl: 
s/(\d+)/($1)/g; 
// PHP: 
$result = preg_replace("/(\d+)/", '($1)', $input); 

Les parenthèses autour (\d+) font un « groupe » en particulier la première (et uniquement dans ce cas) un groupe qui peut être backreferenced dans la chaîne de remplacement. Le drapeau g est requis dans certaines implémentations pour le faire correspondre plusieurs fois dans une seule chaîne). La chaîne de remplacement est assez similaire, bien que certaines langues utilisent \1 au lieu de $1 et certaines autorisent les deux.

0

Selon votre langue, vous cherchez à faire correspondre les groupes.

Donc, en général, vous allez faire un modèle sous la forme de

([0-9]{1,})|([a-zA-Z]{1,}) 

Ensuite, vous itérer sur les groupes résultant en (spécifique à votre langue).

1

La plupart des fonctions de remplacement de regex vous permettent de référencer des groupes de capture spécifiés dans la regex (références arrières a.k.a.), lors de la définition de votre chaîne de remplacement. Par exemple, en utilisant preg_replace() de PHP:

$var = "134kshflskj9809hkj"; 
$result = preg_replace('/(\d+)/', '(\1)', $var); 

// $result now equals "(134)kshflskj(9809)hkj" 

\1 signifie "le premier groupe de capture dans l'expression rationnelle".

1

Une autre solution peu générique est la suivante:

recherche: /([\d]+)([^\d]*)/g
remplacer: ($1)$2

([\d]+): correspondre à un ensemble d'un ou plusieurs chiffres et les conserver dans un groupe
([^\d]*): correspondre à un ensemble de non-chiffres, et les conserver aussi bien. \D pourrait fonctionner ici aussi.
g: indique qu'il s'agit d'une expression globale, pour travailler plusieurs fois sur l'entrée. : Dans le bloc de remplacement, les parens n'ont pas de signification particulière, donc sort le premier groupe, en l'entourant de parens.
$2: sortie le deuxième groupe

j'ai utilisé un pretty good online regex tool pour tester mon expression. La prochaine étape consisterait à l'appliquer à la langue que vous utilisez, car chacun a sa propre nuance d'implémentation.

1

Les références arrières (regroupement) ne sont pas nécessaires si vous cherchez simplement à rechercher des nombres et à les remplacer par l'expression régulière entourée de parenthèses. Il est plus simple d'utiliser toute la correspondance regex dans la chaîne de remplacement.

pour perl par exemple

$text =~ s/\d+/($&)/g; 

Ceci recherche 1 ou plusieurs chiffres et remplace par parens entourant le match (spécifié par $ &), avec queue g pour rechercher et remplacer toutes les occurrences.

voir http://www.regular-expressions.info/refreplace.html pour la syntaxe correcte pour votre langage regex.

Questions connexes