Separator nie może zawierać znaków alfanumerycznych ani odwrotnego ukośnika ani preg_match

88

Mam ten kod:

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

a kiedy uruchamiam, zwraca ten błąd:

Ostrzeżenie: preg_match () [function.preg-match]: separator nie może zawierać znaków alfanumerycznych ani ukośnika odwrotnego

user547363
źródło
2
Uwaga, która może być pomocna dla innych, jeśli przekazujesz wszystkie swoje argumenty preg_match()jako zmienne, upewnij się, że kolejność zmiennych nie została przypadkowo pomieszana w wywołaniu funkcji, ponieważ prawie na pewno spowoduje to to samo pojawia się błąd.
bluebinary
1
Potrzebujesz separatora w ciągu
wyrażenia regularnego
2
Użyj$pattern = "/My name is '(.*)' and im fine/";
gk.

Odpowiedzi:

134

Potrzebujesz separatora dla swojego wzoru. Należy dodać na początku i na końcu wzoru w następujący sposób:

$pattern = "/My name is '(.*)' and im fine/";  // With / as a delimeter 
Paweł
źródło
1
Uważaj na używanie podwójnych cudzysłowów do zamykania wyrażeń regex, w przeciwnym razie niektóre kombinacje znaków \ ​​+ (na przykład \ldo nowego wiersza) zostaną przekonwertowane na ich znak, co może dać inne wyrażenie niż oczekiwano. Użyj apostrofów. Zobacz opis ciągów php .
Patanjali
W tym przykładzie ciąg zawiera pojedyncze cudzysłowy, więc łatwiej jest użyć podwójnych cudzysłowów, aby go ująć (unikając znaku ucieczki, \'który byłby wymagany, gdyby był ujęty w pojedyncze cudzysłowy).
Paul
Wygłosiłem ogólny komentarz, ponieważ ludzie oglądający przykłady mogą uznać je za coś do „wycięcia” dla siebie, nie zdając sobie sprawy z nieprzewidzianych konsekwencji, które mogą się wydarzyć, jeśli rozciągną to na inne sytuacje. Niestety nie mogę zmienić swojego komentarza, aby był jeszcze bardziej szczegółowy.
Patanjali
68

Rozwiązanie (o którym inne odpowiedzi nie wspominają - przynajmniej w czasie, kiedy to pisałem) jest takie, że kiedy PHP odnosi się do ograniczników, nie odnosi się do ograniczników, które widzisz w kodzie (które są cudzysłowami), ale następny znaków w ciągu. (Właściwie nigdy nie widziałem tego nigdzie w żadnej dokumentacji: musisz to zobaczyć w przykładach). Zamiast więc mieć składnię wyrażeń regularnych, taką jak ta, do której możesz być przyzwyczajony w wielu innych językach:

/something/

PHP używa łańcuchów, a następnie szuka w nich innego separatora:

'/something/'

Separator, do którego odnosi się PHP, to para /znaków zamiast pary 'znaków. Więc jeśli piszesz 'something', PHP weźmie sza zamierzony separator i narzeknie, że nie możesz używać znaków alfanumerycznych jako separatora.

Więc jeśli chcesz przekazać (na przykład) an, iaby pokazać, że chcesz dopasować bez uwzględniania wielkości liter, przekazujesz go wewnątrz ciągu, ale poza ogranicznikami wyrażenia regularnego:

'/something/i'

Jeśli chcesz użyć czegoś innego niż /jako separatora, możesz, na przykład, dopasować adres URL i nie chcesz uciekać przed wszystkimi ukośnikami:

'~something~'
ikonoklasta
źródło
1
@Gruber: dzięki! zawsze możesz wysłać swoim znajomym linki do niego i pozwolić im na to głosowanie;)
ikonoklast
1
Wyjaśnienie, czego dokumentacja nie wyjaśnia .. +1 Dziękuję!
Ju Oliveira
Najwyżej głosowana odpowiedź jest taka sama, jak ta, jednak jestem wdzięczny, że mogę teraz zrozumieć, dlaczego jest to poprawna odpowiedź. +1 dzięki!
Eklektyczny
21

W wyrażeniu musisz określić separator. Separator to specjalny znak używany na początku i na końcu wyrażenia w celu wskazania, która część jest wyrażeniem. Dzięki temu możesz używać modyfikatorów i interpretera, aby wiedzieć, które jest wyrażeniem, a które modyfikatorami. Jak stwierdza komunikat o błędzie, separatorem nie może być ukośnik odwrotny, ponieważ ukośnik odwrotny jest znakiem zmiany znaczenia.

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

a poniżej ten sam przykład, ale z imodyfikatorem do dopasowania bez rozróżniania wielkości liter.

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

Jak widać, iznak znajduje się poza ukośnikami i dlatego jest interpretowany jako modyfikator.

Pamiętaj również, że jeśli używasz znaku ukośnika (/) jako separatora, musisz następnie pominąć dalsze użycie / w wyrażeniu regularnym, jeśli występuje.

Ben Swinburne
źródło
7

Wzorzec musi mieć ograniczniki. Ograniczniki mogą być ukośnikiem (/) lub dowolnymi znakami innymi niż alfanumeryczne (#, $, *, ...). Przykłady

$pattern = "/My name is '(.*)' and im fine/"; 
$pattern = "#My name is '(.*)' and im fine#";
$pattern = "@My name is '(.*)' and im fine@";  
Hammad Khan
źródło
0

Może nie jest to związane z oryginalnym przykładem kodu, ale otrzymałem błąd „Separator nie może być alfanumeryczny ani ukośnikiem odwrotnym” i wpisałem go w Google. Powód: pomieszałem kolejność parametrów dla preg_match. Wzorzec był drugim parametrem, a pasujący ciąg był pierwszym. Bądź ostrożny :)

Nubijski
źródło
-2

Spróbuj z tym

 $pattern = "/My name is '\(.*\)' and im fine/"; 
Vikas Naranje
źródło
Po co unikać nawiasów?
Ki Jéy,
1
@kiJey. W sytuacji OP chcieli wyodrębnić nazwę, więc nawiasy są wymagane do dopasowania i dlatego NIE wolno ich zmieniać. Dlatego go odrzucam.
Patanjali