2010-09-30 14 views
3

Je voudrais remplacer les chaînes commençant par "[id", dont la partie centrale est inconnue et se terminant par "]" dans un texte $. Je sais comment remplacer les chaînes qui commencent par "[id" et se termine par "]" mais je ne peux pas comprendre comment inclure la partie du corps intermédiaire inconnue comme règle de remplacement.Comment remplacer une chaîne qui commence par "[id", a une partie médiane inconnue et se termine par "]"?

Des idées comment remplacer comme ça?

Merci.

+1

Je vous suggère d'utiliser des expressions régulières. Utilisez ce site pour vous aider à créer votre modèle de recherche: http://gskinner.com/RegExr/ – clifgriffin

+2

Que faire si la 'partie centrale inconnue' contient un caractère ']'? – Joe

Répondre

5

Ce qui suit va supprimer toutes les occurrences de [idquelque chose]. quelque chose correspondra à tous les caractères sauf ].

$newText = preg_replace('#\[id[^\]]+\]#', '', $subject); 

Si vous savez que quelque chose est toujours un chiffre, vous pouvez utiliser quelque chose comme ceci:

$newText = preg_replace('#\[id\d+\]#', '', $subject); 

Pour plus d'informations sur les expressions régulières, consultez ce site: http://www.regular-expressions.info/.

4

Les fonctions de remplacement de chaîne ne peuvent fonctionner que sur des chaînes spécifiques. Si vous avez un modèle vous voulez correspondre, vous devez utiliser preg_replace, qui remplace basée sur les expressions régulières:

$text = preg_replace('/\[id[^\]]*\]/', $replacement, $text) 
// $replacement is whatever string you want to replace with 

/\[id[^\]]*\]/ est un regular expression (alias regex). Les barres obliques à chaque extrémité sont delimiters dont PHP a besoin pour délimiter une regex. Le reste du motif peut être décrit comme suit:

\[  # match a literal [ character 
id  # match the string "id" 
[^  # open a negated character class 
    \] # match anything other than literal ] character (since it's in a negated class) 
]*  # close the class, repeat it zero or more times 
\]  # match a literal ] 

Concepts:

  • Character classes - une classe de caractères est une façon de décrire qu'un personnage peut être l'une d'une série de possibilités. Les classes de caractères commencent par [ et se terminent par ]. Par exemple, [abc] correspond à aoubouc. Les classes de caractères peuvent être réduits à néant si le premier caractère dans une classe est ^: [^abc] correspond à tout caractère n'est pasaoubouc. Dans notre modèle, [^\]] correspond à n'importe quel caractère qui n'est pas ]. Notez que le ] dans la classe doit être échappé parce que ] signifie généralement la fin de la classe, mais nous voulons spécifier un caractère littéral ]. En utilisant * - Des parties de motifs peuvent être répétées (ce qui permet à un motif de spécifier que quelque chose peut apparaître plusieurs fois). Il y a trois opérateurs de répétition: ? spécifie que quelque chose peut apparaître zéro ou une fois (ie.cela fait partie de votre modèle optional); * spécifie que quelque chose peut apparaître zéro ou plusieurs fois (c'est-à-dire qu'il peut être facultatif, mais il pourrait aussi être un nombre illimité de fois); + spécifie quelque chose qui doit apparaître au moins une fois.
    Dans notre cas; [^\]]* spécifie qu'un caractère qui n'est pas ] peut être recherché zéro ou plusieurs fois - ceci correspondra à une chaîne vide, ou correspondra à abcdefg, car la classe de caractères annulée correspond à 7 fois (car chaque caractère n'est pas ]).
    Notez que, par défaut, les expressions rationnelles sont greedy, ce qui signifie qu'elles correspondent le plus possible à la chaîne; Pour cette raison, [^\]]* lorsqu'il est comparé à abcdefg correspond à la chaîne entière, car c'est la plus grande correspondance possible (même si les sous-chaînes les plus petites correspondent au modèle).

  • Tout le reste de ce modèle correspond littéralement. Comme nous l'avons vu ci-dessus, [ et ] doivent être échappés pour correspondre aux caractères littéraux - car ils ont une signification dans une regex (ie pour définir une classe de caractères) - mais id correspond à un i suivi immédiatement par un d.

Lorsque vous mettez tout cela ensemble, vous vous retrouvez avec un motif qui correspond à un support d'ouverture, suivie par les lettres id, suivi par zéro ou plusieurs caractères et un support de fermeture.

Notez que si vous souhaitez que ce motif soit insensible à la casse, vous pouvez ajouter un i après la barre oblique finale: /\[id[^\]]*\]/i. /i est un modifier qui rend l'ensemble du casse insensible à la casse (donc cela correspondrait également à [ID=...]).

Je recommande de lire le tutorial sur regular-expressions.info si vous n'êtes pas familier avec regexes, car il vous donnera une très bonne compréhension de ce qu'ils font et comment les composer.

+0

+1 une des meilleures explications de regex que j'ai vu! –

2

utilisant preg_replace():

<?php 

    $text = "[hi=hello] [id=hellomynameisjoe] [hello=hi]"; 
    $new = preg_replace('@\[id[^\]]+\]@', '[replaced!]', $text); 
    echo $new; 
?> 
+0

J'aime cette syntaxe. Très lisible – Armstrongest

+1

Notez que les modèles paresseux sont moins efficaces car ils causent beaucoup de retour en arrière. Voir http://blog.stevenlevithan.com/archives/greedy-lazy-performance –

+0

Je me demande pourquoi je suis tellement habitué à ça. Merci pour l'info, éditer mon code. – Ruel