Разделитель не должен быть буквенно-цифровым или обратным слэшем и preg_match.

87

У меня есть такой код:

$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]: разделитель не должен быть буквенно-цифровым или обратным слэшем.

user547363
источник
2
В качестве примечания, которое может быть полезно для других, если вы передаете все свои аргументы preg_match()как переменные, убедитесь, что вы не получили случайный порядок переменных в вызове функции, так как это почти наверняка приведет к тому же самому появляется ошибка.
bluebinary 09
1
Вам нужен разделитель в строке регулярного выражения
Ki Jéy
2
Использование$pattern = "/My name is '(.*)' and im fine/";
gk.

Ответы:

134

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

$pattern = "/My name is '(.*)' and im fine/";  // With / as a delimeter 
Павел
источник
Остерегайтесь использования двойных кавычек для заключения регулярных выражений, иначе некоторые комбинации символов \ + (например, \lдля перевода строки) будут преобразованы в их символ, что может привести к выражению, отличному от ожидаемого. Используйте одинарные кавычки. См. Описание строк php .
Патанджали
В этом примере строка включает одинарные кавычки, поэтому для ее заключения проще использовать двойные кавычки (избегая экранирования \', которое потребовалось бы, если бы она была заключена в одинарные кавычки).
Пол
Я делал общий комментарий, поскольку люди, просматривающие примеры, могут воспринимать их как нечто «вырезанное из печенья» для себя, не осознавая непредвиденных последствий, которые могут произойти, если они распространят это на другие ситуации. К сожалению, я не могу изменить свой комментарий на более конкретный.
Патанджали
68

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

/something/

PHP использует строки, а затем ищет внутри строки другой разделитель:

'/something/'

Разделитель, на который ссылается PHP, - это пара /символов, а не пара 'символов. Поэтому, если вы напишете 'something', PHP будет использовать sкак предполагаемый разделитель и пожаловаться, что вам не разрешено использовать буквенно-цифровые символы в качестве разделителя.

Поэтому, если вы хотите передать (например), iчтобы показать, что вы хотите совпадение без учета регистра, вы передаете его внутри строки, но за пределами разделителей регулярных выражений:

'/something/i'

Если вы хотите использовать что-то другое, кроме /как разделитель, вы можете, например, если вы сопоставляете URL-адрес и не хотите экранировать все косые черты:

'~something~'
иконоборец
источник
1
@Gruber: спасибо! вы всегда можете отправить ссылки на него всем своим друзьям и позволить им проголосовать за него;)
iconoclast
1
Объясняя, какая документация не объясняет .. +1 Спасибо!
Джу Оливейра
Ответ, получивший наибольшее количество голосов, такой же, как этот, однако я благодарен за то, что теперь понимаю, почему это правильный ответ. +1 Спасибо!
Eclectic
21

Вы должны указать разделитель для вашего выражения. Разделитель - это специальный символ, используемый в начале и в конце выражения, чтобы обозначить, какая часть является выражением. Это позволяет вам использовать модификаторы и интерпретатор, чтобы узнать, что является выражением, а какие - модификаторами. Как указано в сообщении об ошибке, разделитель не может быть обратной косой чертой, поскольку обратная косая черта является escape-символом.

$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 они хотели извлечь имя, поэтому круглые скобки необходимы для совпадения и, следовательно, НЕ должны быть экранированы. Вот почему я голосую против него.
Патанджали