Le délimiteur ne doit pas être alphanumérique ou antislash et preg_match

87

J'ai ce code:

$string1 = "My name is 'Kate' and im fine"; 
$pattern = "My name is '(.*)' and im fine"; 
preg_match($pattern , $string1, $matches);
echo $matches[1];

et quand je suis exécuté, il renvoie cette erreur:

Attention: preg_match () [function.preg-match]: Le délimiteur ne doit pas être alphanumérique ou antislash

user547363
la source
2
Comme note qui peut être utile pour les autres, si vous passez tous vos arguments en preg_match()tant que variables, assurez-vous de ne pas mélanger accidentellement l'ordre des variables dans l'appel de fonction, car cela entraînera presque certainement le même résultat erreur apparaissant.
bluebinary
1
Vous avez besoin d'un délimiteur dans votre chaîne de regexp
Ki Jéy
2
Utilisez$pattern = "/My name is '(.*)' and im fine/";
gk.

Réponses:

134

Vous avez besoin d'un délimiteur pour votre motif. Il doit être ajouté au début et à la fin du motif comme ceci:

$pattern = "/My name is '(.*)' and im fine/";  // With / as a delimeter 
Paul
la source
Méfiez-vous des guillemets doubles pour encapsuler les expressions regex, sinon certaines combinaisons de caractères \ + (comme \lpour le saut de ligne) seront converties en leur caractère, ce qui pourrait bien produire une expression différente de celle attendue. Utilisez des guillemets simples. Voir la description des chaînes php .
Patanjali
Dans cet exemple, la chaîne comprend des guillemets simples, il est donc plus facile d'utiliser des guillemets doubles pour la délimiter (en évitant les échappements \'qui seraient nécessaires si elle était entourée de guillemets simples).
Paul
Je faisais un commentaire général, car les gens qui regardent des exemples peuvent les prendre comme quelque chose à «couper les biscuits» pour eux-mêmes, ne réalisant pas les conséquences imprévues qui peuvent se produire s'ils l'étendent à d'autres situations. Malheureusement, je ne peux pas modifier mon commentaire pour être encore plus précis.
Patanjali
68

La solution (que les autres réponses ne mentionnent pas - du moins au moment où j'ai écrit ceci) est que lorsque PHP fait référence à des délimiteurs, il ne fait pas référence aux délimiteurs que vous voyez dans votre code (qui sont des guillemets) mais au suivant caractères à l'intérieur de la chaîne. (En fait, je n'ai jamais vu cela déclaré nulle part dans aucune documentation: vous devez le voir dans des exemples.) Donc, au lieu d'avoir une syntaxe d'expression régulière comme celle à laquelle vous êtes habitué dans de nombreux autres langages:

/something/

PHP utilise des chaînes, puis cherche dans la chaîne un autre délimiteur:

'/something/'

Le délimiteur auquel PHP fait référence est la paire de /caractères, au lieu de la paire de 'caractères. Donc, si vous écrivez 'something', PHP prendras comme délimiteur prévu et se plaindra que vous n'êtes pas autorisé à utiliser des caractères alphanumériques comme délimiteur.

Donc, si vous voulez passer (par exemple) un ipour montrer que vous voulez une correspondance insensible à la casse, vous le passez à l'intérieur de la chaîne mais en dehors des délimiteurs de regex:

'/something/i'

Si vous voulez utiliser autre chose que /votre délimiteur, vous pouvez, par exemple si vous correspondez à une URL et que vous ne voulez pas avoir à échapper toutes les barres obliques:

'~something~'
iconoclaste
la source
1
@Gruber: merci! vous pouvez toujours envoyer tous vos amis des liens vers et les laisser Upvote il;)
iconoclaste
1
Expliquer ce que la documentation n'explique pas .. +1 Merci!
Ju Oliveira
La réponse la plus élevée est la même que celle-ci, cependant, je suis reconnaissant de comprendre maintenant pourquoi c'est la bonne réponse. +1 Merci!
Eclectic
21

Vous devez spécifier un délimiteur pour votre expression. Un délimiteur est un caractère spécial utilisé au début et à la fin de votre expression pour indiquer quelle partie est l'expression. Cela vous permet d'utiliser des modificateurs et l'interpréteur pour savoir qui est une expression et lesquels sont des modificateurs. Comme l'indique le message d'erreur, le délimiteur ne peut pas être une barre oblique inverse car la barre oblique inverse est le caractère d'échappement.

$pattern = "/My name is '(.*)' and im fine/";

et ci-dessous le même exemple mais avec le imodificateur pour correspondre sans être sensible à la casse.

$pattern = "/My name is '(.*)' and im fine/i";

Comme vous pouvez le voir, le iest en dehors des barres obliques et est donc interprété comme un modificateur.

Gardez également à l'esprit que si vous utilisez une barre oblique (/) comme délimiteur, vous devez alors échapper aux autres utilisations de / dans l'expression régulière, si elle est présente.

Ben Swinburne
la source
7

Le modèle doit avoir des délimiteurs. Les délimiteurs peuvent être une barre oblique (/) ou des caractères non alphanumériques (#, $, *, ...). Exemples

$pattern = "/My name is '(.*)' and im fine/"; 
$pattern = "#My name is '(.*)' and im fine#";
$pattern = "@My name is '(.*)' and im fine@";  
Hammad Khan
la source
0

Peut-être pas lié à l'exemple de code original, mais j'ai reçu l'erreur «Le délimiteur ne doit pas être alphanumérique ou antislash» et googlé ici. Raison: j'ai mélangé l'ordre des paramètres pour preg_match. Le modèle était le deuxième paramètre et la chaîne à correspondre était la première. Faites attention :)

nubien
la source
-2

Veuillez essayer avec ceci

 $pattern = "/My name is '\(.*\)' and im fine/"; 
Vikas Naranje
la source
Pourquoi échapper aux parenthèses?
Ki Jéy
1
@kiJey. Dans la situation de l'OP, ils voulaient extraire le nom, donc les parenthèses sont obligatoires pour la correspondance et ne doivent donc PAS être échappées. C'est pourquoi je vote défavorablement.
Patanjali