2009-06-26 5 views
0

Je dispose d'un fichier de texte comme siComment puis-je faire une regex pas 'avaler' un personnage?

{word} definition 
{another word} another definition {word} they don't have to be on different lines 

Le regex j'utilisais était

$regex = '/\{([a-z]+?)\}(.+?)\{/i'; 

Ceci, cependant, pose des problèmes en ce qu'elle avale la dernière accolade {, puis il a gagné » t correspond au prochain {dans le mot suivant.

Pour démontrer, je l'ai fait à des fins de débogage

echo preg_replace($regex, '<b style="background-color: red;">$1</b><b style="background-color: yellow;">$2</b>', $content); 

Voici un exemple de ma sortie (notez l'accolade d'ouverture dans le mot suivant est pas là, il ne trouve donc pas dans l'expression régulière)

<b style="background-color: red;">shrub</b><b style="background-color: yellow;"> Multi stemmed woody plant</b>Abaxial} side or face away from the axis 

Comment puis-je modifier mon regex pour que cela fonctionne? Merci

EDIT

Un grand merci pour vos réponses. J'ai changé mon regex comme si

$regex = '/\{([a-z\-\s]+?)\}([^\{]+)/i'; 

Je vais aussi regarder dans les articles lookahead.

Répondre

7

Pour ce cas précis, vous pouvez faire:

$regex = '/\{([a-z]+?)\}([^\{]+)/i'; 

[^\{] signifie "correspond à tout caractère qui n'est pas une accolade gauche". Cela a également l'avantage de ne pas nécessiter de { à la fin de votre saisie. Plus généralement, vous pouvez également utiliser des assertions lookahead comme d'autres l'ont mentionné.

2

Vous voudrez utiliser la fonctionnalité Look Ahead pour trouver un caractère, sans le capturer.

Vous pourriez restructurer votre regex comme tel.

$regex = '/\{([a-z]+?)\}(.+?)(?={)'; 
2

Vous pouvez changer la dernière partie pour correspondre uniquement des accolades non bouclés au lieu de .+ suivi d'une accolade, comme ceci:

$regex = '/\{([a-z]+?)\}([^{]+)/i'; 
Questions connexes