Нежелательное регулярное выражение

Мне нужно получить значение внутри некоторых тегов в файле комментариев php, как это

php code /* this is a comment !- <titulo>titulo3</titulo> <funcion> <descripcion>esta es la descripcion de la funcion 6</descripcion> </funcion> <funcion> <descripcion>esta es la descripcion de la funcion 7</descripcion> </funcion> <otros> <descripcion>comentario de otros 2a hoja</descripcion> </otros> -! */ some php code 

так как вы можете видеть, что у файла есть символы новой строки и повторения тегов типа <funcion></funcion> и мне нужно получить каждый из тегов, поэтому я пытался что-то вроде этого:

 preg_match_all("/(<funcion>)(.*)(<\/funcion>)/s",$file,$matches); 

этот пример работает с новыми линиями, но его жадным, поэтому я искал и видел эти два решения:

 preg_match_all("/(<funcion>)(.*?)(<\/funcion>)/s",$file,$matches); preg_match_all("/(<funcion>)(.*)(<\/funcion>)/sU",$file,$matches); 

но никто из них не работает для меня, не знаю, почему

Попробуйте использовать [\s\S] , что означает все пробельные и непространственные символы, а не . , Кроме того, нет необходимости добавлять <funcion> и </funcion> в группы соответствия.

 /<funcion>([\s\S]*?)<\/funcion>/s 

Кроме того, имейте в виду, что лучший способ сделать это – синтаксический анализ XML с помощью анализатора XML . Даже если это не документ XML, как вы упомянули в своем комментарии, извлеките часть, которая должна быть проанализирована, и используйте синтаксический анализатор XML для его анализа.

Это выражение из вашего вопроса:

 preg_match_all("/(<funcion>)(.*?)(<\/funcion>)/s", $file, $matches); print_r($matches); 

Это будет работать, но ТОЛЬКО IF $file – это строка, содержащая XML; если это имя файла, вам нужно сначала получить содержимое:

 preg_match_all("/(<funcion>)(.*?)(<\/funcion>)/s", file_get_contents($file), $matches); 

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

Попробуй это..

  /<funcion>((.|\n)*?)<\/funcion>/i 

Например

 $srting = "<titulo>titulo3</titulo> <funcion> <descripcion>esta es la descripcion de la funcion 6</descripcion> </funcion> <funcion> <descripcion>esta es la descripcion de la funcion 7</descripcion> </funcion> <otros> <descripcion>comentario de otros 2a hoja</descripcion> </otros>"; $result=preg_match_all('/<funcion>((.|\n)*?)<\/funcion>/i', $srting,$m); print_r($m[0]); 

Этот результат

 Array ( [0] => esta es la descripcion de la funcion 6 [1] => esta es la descripcion de la funcion 7 ) 

DEMO

, , Если структура точно такая же (всегда отступы внутри содержимого), вы можете легко сопоставить ее с / \ n [\ s] + ([^ \ n] + (\ n [\ s] +) *) \ n / .

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

, , Попробуй это:

 $regexp = '/<funcion>\n[\s]+([^\n]+(\n[\s]+)*)\n</funcion>/'; $works = preg_match_all($regexp, $file, $matches); echo '<pre>'; print_r($matches); 

, , Массив «$ matches [1]» даст вам массив содержимого тегов «funcion».

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

, , Повеселись.