2012-06-04 1 views
2

Я предполагаю, что это более или менее вопрос из двух частей, но вот основные сведения: я пишу PHP, чтобы использовать preg_match_all для поиска в переменной для строк, заканчивающейся буквой {}. Затем он повторяется через каждую возвращаемую строку, заменяет найденные строки данными из запроса MySQL.Синтаксис Regex PCRE

Первый вопрос заключается в следующем: какие-либо хорошие сайты, чтобы действительно узнать, что такое выражения PCRE? Я много искал в Google, но лучший из них, который я смог найти, - http://www.regular-expressions.info/. На мой взгляд, информация там не очень хорошо организована, и, поскольку я бы предпочел не повесить трубку, чтобы просить о помощи, когда мне нужно написать сложное регулярное выражение, пожалуйста, укажите мне пару сайтов (или пару книг!) что поможет мне не беспокоить вас в будущем.

Второй вопрос заключается в следующем: У меня есть это регулярное выражение

"/{.*(_){1}(.*(_){1}[a-z]{1}|.*)}/" 

и мне нужно, чтобы поймать экземпляры, такие как {first_name}, {last_name}, {email} и т.д. У меня есть три проблемы с этим регулярным выражением.

Во-первых, он видит «{first_name} {last_name}» как одну строку, когда он должен видеть это как два. Я смог решить это, проверив существование пространства, а затем взрыва в пространстве. Беспокойный, но он работает.

Вторая проблема заключается в том, что она включает пунктуацию как часть захваченной строки. Итак, если у вас есть «{first_name} {last_name}», то он возвращает запятую как часть строки. Я смог частично решить эту проблему, просто используя preg_replace для удаления периодов, запятых и полуколоней. Хотя он работает для этих пунктов пунктуации, моя логика неспособна обрабатывать восклицательные знаки, вопросительные знаки и все остальное.

Третья проблема с этим регулярным выражением заключается в том, что он не видит экземпляры {email} вообще.

Теперь, если вы можете, готовы, и у вас есть время, чтобы просто передать мне решение этой проблемы, спасибо, потому что это решит мою непосредственную проблему. Однако, даже если вы можете это сделать, пожалуйста, , пожалуйста, предоставить lmgfty, который предоставляет хорошие веб-сайты в качестве ссылок и/или книги или двух, которые обеспечили бы хорошее образование по этому вопросу. Сайты были бы предпочтительнее, поскольку деньги были жесткими, но если книга является решением, я найду деньги (если моя локальная библиотечная система не сможет забрать указанный объем).

+2

Мне очень понравилось [Освоение регулярных выражений] (http://www.amazon.com/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124). В этой книге больше, чем вы, вероятно, когда-либо будете использовать; очень тщательный. –

+0

@JonahBishop: это хорошая книга, но не совсем легко переварить;) – 0xC0000022L

+0

@ClementSmith: вы говорите, что это должно увидеть это как два, но ваше регулярное выражение жадное. Добавьте несколько «?» В нужные места :) – 0xC0000022L

ответ

4

Тогда я нашел собственный PCRE синтаксис ссылки в PHP довольно хороший: http://uk.php.net/manual/en/reference.pcre.pattern.syntax.php

Давайте поговорим о вашем выражении. Это довольно много подробностей, чем необходимо; Я собираюсь упростить его, пока мы это переживаем.

Более простой способ взглянуть на то, что вы пытаетесь сопоставить: «найти {, затем любое количество букв или символов подчеркивания, затем }». Регулярное выражение для этого (в синтаксисе строки-y PHP): '/\{[a-z_]+\}/'

Это будет соответствовать всем вашим примерам, но также и некоторым более диким, например {__a_b}. Если это не вариант, мы можем пойти с несколько более сложным описанием: «найдите {, затем кучу букв, затем (как можно чаще) символ подчеркивания, за которым следует куча букв, а затем }». В регулярном выражении: /\{([a-z]+(_[a-z]+)*\}/

Это, возможно, потребуется немного больше объяснений. Поскольку мы хотим повторить то, что соответствует _foo сегментам, нам нужно поместить его в круглые скобки.Затем мы говорим: попробуйте найти это как можно чаще, но это тоже нормально, если вы его вообще не найдете (вот в чем смысл *).

Так что теперь у нас есть с чем сравнить ваши попытки, давайте посмотрим на то, что причиной ваших проблем:

  • Ваше выражение соответствует любым символам внутри {}, включая } и { и целый букет другие вещи. Другими словами, {abcde{_fgh} будет приниматься вашим регулярным выражением, равно как {abcde} fg_h {ijkl}.
  • У вас есть обязательный _ там, сразу после первого .*. (_){1} (что означает точно то же, что и _) говорит: что бы ни случилось, взорвется, если этого здесь нет! Очевидно, вы этого не хотите, потому что он никогда не будет соответствовать {email}.

Вот полное описание на простом языке, что соответствует Вашему регулярное выражение:

  1. Совпадение {.
  2. Соответствие _.
  3. Матч абсолютно ничего, если вы можете соответствовать всем остальным правилам сразу после этого.
  4. Соответствие _.
  5. Соответствие одной букве.
  6. Вместо этого _ и единственное письмо, абсолютно ничего в порядке, тоже.
  7. Соответствие }.

Это, вероятно, довольно далеко от того, что вы хотели. Не волнуйся. Регулярные выражения требуют времени, чтобы привыкнуть. Я думаю, что это очень полезно, если вы думаете об этом с точки зрения инструкций, т. Е. При создании регулярного выражения, попытайтесь построить его в своей голове как «найти это, затем найти» и т. Д. Затем выведите правильный синтаксис для достижения именно это.

Это сложно в основном потому, что не все инструкции, которые вы можете придумать в своей голове, легко перевести в кусок регулярного выражения ... но вот откуда приходит опыт. Я обещаю вам, что вы его получите нет времени вообще ... если вы довольно методично о создании своих регулярных выражений вначале.

Удачи вам! :)

+0

Спасибо за это. Раньше я не думал думать о регулярных выражениях. Наверное, это просто до неопытности. Я ценю ваш ответ и разместил эту страницу для дальнейшего использования. (У меня также есть книга, предложенная @JonahBishop по заказу из библиотеки) –

+0

спасибо за ссылку. :) – jsbisht

1

Для PCRE, я просто переварил PCRE Справочника, но потом мой мозг работает таким образом в любом случае ...

Что касается соответствия разделителей вещи, вы, как правило, 2 подхода:

  1. Match первый разделитель, сопоставляйте все, что не является закрывающим разделителем, соответствуют разделителю закрытия.
  2. Соответствует первому разделителю, соответствует любому ungreedily, соответствует закрытию разделителя.

E.g.для Вашего случая:

  1. \{([^}]+)\}
  2. \{(.+?)\} - Обратите внимание на ? после +

я добавил группу вокруг содержания вы, вероятно, хотели бы извлечь тоже.

Обратите также внимание на то, что в случае № 1 в частности, но также и для № 2, если действует «точка соответствует чему-либо» (точка, одиночная линия или любое другое ваше любимое выражение регулярного выражения вызывает это), что они также будут соответствовать разрыву строк внутри - вам нужно вручную исключить это и все, что вы не хотите, если это будет проблемой; см. приведенный выше ответ, если вы хотите, чтобы что-то больше напоминало «белый список».

0
  1. Адрес good regex site.
  2. Вот PCRE регулярное выражение, которое будет работать: \{\w+\}

Вот как это работает: Это в основном ищет { с последующим one ore more word characters с последующим }. Интересная часть состоит в том, что слово character class на самом деле включает в себя и подчеркивание. \w по существу сокращенно [A-Za-z0-9_]

Таким образом, он будет в основном соответствовать любой комбинации этих символов в фигурных скобках, и из-за знака «плюс» будут соответствовать только фигурные скобки, которые не пусты.

 Смежные вопросы

  • Нет связанных вопросов^_^