Регулярное выражение повторяется внутри шаблона - PullRequest
1 голос
/ 09 марта 2012

У меня есть следующий текст, и я хотел бы preg_match_all, что находится внутри { и }, если оно содержит только a-zA-Z0-9 и :

some text,{SOMETHING21} {SOMETHI32NG:MORE}some msdf{TEXT:GET:2}sdfssdf sdf sdf

Я пытаюсь найти соответствие {SOMETHING21} {SOMETHI32NG:MORE} {TEXT:GET:2}. В теге может быть несколько :.

То, что у меня сейчас есть:

preg_match_all('/\{([a-zA-Z0-9\-]+)(\:([a-zA-Z0-9\-]+))*\}/', $from, $matches, PREG_SET_ORDER);

Этоработает, как и ожидалось, для {SOMETHING21} и {SOMETHI32NG:MORE}, но для {TEXT:GET:2} он соответствует только TEXT и 2

, поэтому он соответствует только первому и последнему слову в теге и оставляет средние словаиз массива $matches.Это вообще возможно, или я должен просто сопоставить их и затем взорваться на :?

- edit -

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

Я надеюсь, что следующее очистит его abit more:

\{                              // the match has to start with {
([a-zA-Z0-9\-]+)                // after the { the match needs to have alphanum consisting out of 1 or more characters
(
    \:                          // if we have : it should be followed by alphanum consisting out of 1 or more characters
    ([a-zA-Z0-9\-]+)            // <---- !! this is what it is about !! even though this subexpression is between brackets it is not put into $matches if more then one of these is found
)*                              // there could be none or more of the previous subexpression
\}                              // the match has to end with }

Ответы [ 3 ]

2 голосов
/ 09 марта 2012

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

Итак, вы должны соответствовать шаблону:

preg_match_all('/{([a-z\d-]+(?::[a-z\d-]+)*)}/i', $from, $matches);

, а затем разбить каждый элемент на $matches[1] на :.

1 голос
/ 09 марта 2012

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

$from = "some text,{SOMETHING21} {SOMETHI32NG:MORE}some msdf{TEXT:GET:2}sdfssdf sdf sdf";
preg_match_all('/\{((?:[a-zA-Z0-9\-]+)(?:\:(?:[a-zA-Z0-9\-]+))*)\}/', $from, $matches, PREG_SET_ORDER);
print_r($matches);

Результат:

Array
(
    [0] => Array
    (
        [0] => {SOMETHING21}
        [1] => SOMETHING21
    )

    [1] => Array
    (
        [0] => {SOMETHI32NG:MORE}
        [1] => SOMETHI32NG:MORE
    )

    [2] => Array
    (
        [0] => {TEXT:GET:2}
        [1] => TEXT:GET:2
    )

)
0 голосов
/ 09 марта 2012

Может быть, я не понял требования, но ...

preg_match_all('/{[A-Za-z0-9:-]+}/', $from, $matches, PREG_PATTERN_ORDER);

приводит к:

Array
(
    [0] => Array
        (
            [0] => {SOMETHING21}
            [1] => {SOMETHI32NG:MORE}
            [2] => {TEXT:GET:2}
        )
)
...