Розділювач не повинен бути буквено-цифровим або зворотною рискою рискою та preg_match


86

У мене є такий код:

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

і при їх запуску він повертає цю помилку:

Попередження: preg_match () [function.preg-match]: Роздільник не повинен бути буквено-цифровим або зворотною косою рисою


2
Як примітка, яка може бути корисною для інших, якщо ви передаєте всі свої аргументи preg_match()як змінні, переконайтесь, що ви не отримали порядок змінних, випадково змішаних у виклику функції, оскільки це також майже напевно призведе до того самого з'являється помилка.
bluebinary

1
Вам потрібен роздільник у вашому рядку регулярних виразів
Кі Джей,

2
Використання$pattern = "/My name is '(.*)' and im fine/";
gk.

Відповіді:


133

Вам потрібен роздільник для вашого малюнка. Його слід додати на початку та в кінці шаблону так:

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

Обережно, використовуйте подвійні лапки для вкладання виразів регулярних виразів, інакше деякі комбінації символів \ + (наприклад, \lдля подачі рядків) будуть перетворені в їхній символ, що цілком може створити вираз, відмінний від очікуваного. Використовуйте одинарні лапки. Див. Опис рядків php .
Патанджалі

У цьому прикладі рядок включає одинарні лапки, тому легше використовувати подвійні лапки, щоб укласти його (уникаючи екранування, \'яке було б потрібно, якщо б воно було вкладено в одинарні лапки).
Пол

Я робив загальний коментар, оскільки люди, які переглядають приклади, можуть сприймати їх як щось «вирізане для печива» для себе, не розуміючи непередбачених наслідків, які можуть статися, якщо вони поширять це на інші ситуації. На жаль, я не можу змінити свій коментар на більш конкретний.
Патанджалі,

68

Рішення (яке в інших відповідях не згадується - принаймні на момент написання цього матеріалу) полягає в тому, що коли PHP посилається на роздільники, це стосується не роздільників, які ви бачите у своєму коді (це лапки), а наступного символів усередині рядка. (Насправді я ніколи не бачив цього ніде в жодній документації: це потрібно бачити на прикладах.) Отже, замість того, щоб мати синтаксис регулярного виразу, подібний до того, до якого ви звикли з багатьох інших мов:

/something/

PHP використовує рядки, а потім шукає всередині рядка інший роздільник:

'/something/'

Розділювач, на який посилається PHP, - це пара /символів, а не пара 'символів. Отже, якщо ви пишете 'something', PHP сприйме sяк передбачуваний роздільник і скаржиться, що вам заборонено використовувати буквено-цифрові символи як роздільник.

Отже, якщо ви хочете передати (наприклад) an, iщоб показати, що ви хочете відповідати регістру, не враховуючи регістр, ви передаєте його всередині рядка, але поза роздільниками регулярних виразів:

'/something/i'

Якщо ви хочете використовувати щось інше, ніж /як свій роздільник, ви можете, наприклад, якщо ви збігаєтеся з URL-адресою і не хочете, щоб уникнути всіх похилих рисок:

'~something~'

1
@Gruber: дякую! Ви завжди можете надіслати всім своїм друзям посилання на нього і дозволити їм проголосувати за це;)
іконоборці

1
Пояснення, яка документація не пояснює .. +1 Дякую!
Ju Oliveira

Відповідь, яка отримала найбільшу оцінку, така ж, як і ця, однак я вдячний, що тепер розумію, чому це правильна відповідь. +1 Дякую!
Еклектика

21

Ви повинні вказати роздільник для виразу. Розділювач - це спеціальний символ, який використовується на початку та в кінці виразу для позначення, якою частиною є вираз. Це дозволяє використовувати модифікатори та інтерпретатор, щоб знати, що таке вираз, а що модифікатори. Як зазначено в повідомленні про помилку, роздільник не може бути зворотною рискою рискою, оскільки зворотна коса риса є символом екранування.

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

і нижче того самого прикладу, але з iмодифікатором для збігу, не враховуючи регістр.

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

Як бачите, значення iза межами косої риски є, і тому інтерпретується як модифікатор.

Також майте на увазі, що якщо ви використовуєте в якості роздільника символ косої риски (/), то вам слід уникнути подальшого використання / у регулярному виразі, якщо він присутній.


7

Шаблон повинен мати роздільники. Розділювачі можуть бути косою рискою (/) або будь-якими нелітерально-цифровими символами (#, $, *, ...). Приклади

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


0

Можливо, це не пов'язано з оригінальним прикладом коду, але я отримав повідомлення про помилку "Розділювач не повинен бути буквено-цифровим або зворотною рискою рискою" і погуглив тут. Причина: я змішав порядок параметрів для preg_match. Шаблон був другим параметром, а рядок, що збігався, був першим. Будь обережний :)


-2

Будь ласка, спробуйте з цим

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

Навіщо уникати дужок?
Ki Jéy

1
@kiJey. У ситуації OP вони хотіли витягти ім'я, тому дужки потрібні для збігу, і тому НЕ повинні бути екрановані. Ось чому я його проти.
Патанджалі,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.