O delimitador não deve ser alfanumérico ou barra invertida e preg_match

87

Eu tenho este código:

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

e quando sou executado, ele retorna este erro:

Aviso: preg_match () [function.preg-match]: O delimitador não deve ser alfanumérico ou barra invertida

user547363
fonte
2
Como uma observação que pode ser útil para outros, se você estiver passando todos os seus argumentos para preg_match()como variáveis, certifique-se de não misturar a ordem das variáveis ​​acidentalmente na chamada de função, pois isso quase certamente resultará no mesmo erro aparecendo.
bluebinary
1
Você precisa de um delimitador em sua string regexp
Ki Jéy
2
Use$pattern = "/My name is '(.*)' and im fine/";
gk.

Respostas:

134

Você precisa de um delimitador para seu padrão. Deve ser adicionado no início e no final do padrão, assim:

$pattern = "/My name is '(.*)' and im fine/";  // With / as a delimeter 
Paulo
fonte
Cuidado ao usar aspas duplas para incluir expressões regex, caso contrário, algumas combinações de caracteres \ + (como \lpara alimentação de linha) serão convertidas em seus caracteres, o que pode muito bem produzir uma expressão diferente do esperado. Use aspas simples. Veja a descrição de php Strings .
Patanjali
Neste exemplo, a string inclui aspas simples, portanto, é mais fácil usar aspas duplas para incluí-la (evitando o escape \'que seria necessário se estivesse entre aspas simples).
Paul de
Eu estava fazendo um comentário geral, já que as pessoas que veem os exemplos podem considerá-los como algo a ser cortado por si mesmas, sem perceber as consequências imprevistas que podem acontecer se eles se estenderem a outras situações. Infelizmente, não posso mudar meu comentário para ser ainda mais específico.
Patanjali
68

A solução (que outras respostas não mencionam - pelo menos no momento em que escrevi isso originalmente) é que quando PHP se refere a delimitadores, não está se referindo aos delimitadores que você vê em seu código (que são aspas), mas o próximo caracteres dentro da string. (Na verdade, nunca vi isso declarado em nenhuma documentação: você tem que ver em exemplos.) Então, em vez de ter uma sintaxe de expressão regular como a que você está acostumado em muitas outras linguagens:

/something/

O PHP usa strings e, em seguida, procura outro delimitador dentro da string :

'/something/'

O delimitador ao qual o PHP está se referindo é o par de /caracteres, ao invés do par de 'caracteres. Portanto, se você escrever 'something', o PHP tomará scomo delimitador pretendido e reclamará que você não tem permissão para usar caracteres alfanuméricos como delimitador.

Portanto, se você quiser passar (por exemplo) um ipara mostrar que deseja uma correspondência não sensível a maiúsculas e minúsculas, passe-o dentro da string, mas fora dos delimitadores regex:

'/something/i'

Se quiser usar algo diferente de /seu delimitador, você pode, por exemplo, se estiver correspondendo a um URL e não quiser ter que escapar todas as barras:

'~something~'
iconoclasta
fonte
1
@Gruber: obrigado! você sempre pode enviar links para todos os seus amigos e permitir que eles votem;)
iconoclast
1
Explicando o que a documentação não explica .. +1 Obrigado!
Ju Oliveira
A resposta com maior número de votos positivos é a mesma, no entanto, estou grato por agora entender porque essa é a resposta correta. +1 Obrigado!
Eclético
21

Você deve especificar um delimitador para sua expressão. Um delimitador é um caractere especial usado no início e no final de sua expressão para denotar qual parte é a expressão. Isso permite que você use modificadores e o interpretador para saber o que é uma expressão e quais são os modificadores. Como afirma a mensagem de erro, o delimitador não pode ser uma barra invertida porque a barra invertida é o caractere de escape.

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

e abaixo do mesmo exemplo, mas com o imodificador para corresponder sem diferenciar maiúsculas de minúsculas.

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

Como você pode ver, o iestá fora das barras e, portanto, é interpretado como um modificador.

Também tenha em mente que se você usar um caractere de barra (/) como um delimitador, você deve escapar de outros usos de / na expressão regular, se houver.

Ben Swinburne
fonte
7

O padrão deve ter delimitadores. Delimitadores podem ser uma barra (/) ou quaisquer caracteres não alfanuméricos (#, $, *, ...). Exemplos

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

Talvez não relacionado ao exemplo de código original, mas recebi o erro "O delimitador não deve ser alfanumérico ou barra invertida" e pesquisei aqui. Motivo: misturei a ordem dos parâmetros para preg_match. O padrão foi o segundo parâmetro e a string correspondente foi a primeira. Seja cuidadoso :)

Núbio
fonte
-2

Por favor tente com isto

 $pattern = "/My name is '\(.*\)' and im fine/"; 
Vikas Naranje
fonte
Por que escapar dos parênteses?
Ki Jéy
1
@kiJey. Na situação do OP, eles queriam extrair o nome, então os parênteses são necessários para a correspondência e, portanto, NÃO devem ser escapados. É por isso que estou rejeitando.
Patanjali