• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Bruno

Ajuda em expressões regulares

23 mensagens neste tópico

Boas, estou aqui atrofiar com algo que deve ser mto simples...

Quero apanhar o conteúdo entre [*] e [/*] em:
[list]
[*]01[/*][*]02[/*][*]03[/*]
[*]04[/*]
[*]05[/*]

[*]06[/*]
[/list]

Alguém consegue ajudar-me?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Ora, tenta lá assim:

<?php
$string ="[list]
[*]01[/*][*]02[/*][*]03[/*]
[*]04[/*]
[*]05[/*]

[*]06[/*]
[/list]";

preg_match_all("/(\[\*\])(.*?)(\[\/\*\])/i", $string, $conteudo);

foreach($conteudo[2] as $valor) {
 echo "$valor<br/>";
}
?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

fazes  " (0\d*)+" , neste caso tb apanhas 00, ou 0, ou 000... e depois tb apanhas 09, 010, 111...  não sei se é isso que queres. Se não for diz kualker coisa  ;)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Funciona mas não é o que pretendo  Faltou referenciar q tem de ter [list] antes e [/list] depois :$

Obrigado

Tool: é suposto apanhar caracteres tb :D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

preg_match_all("/\[List\]((\[\*\])(.*?)(\[\/\*\]))*\[List\]/i", $string, $conteudo);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É assim, isto não é certamente o método mais indicado, mas assim de repente, aqui vai:

<?php
$string ="[*]ab[/*][list][*]01[/*][*]02[/*][*]03[/*][*]04[/*][*]05[/*][*]06[/*][/list][*]cd[/*]";


preg_match_all("/(\[list\])(.*?)(\[\/list\])/i", $string, $valor);

$x = "";

foreach($valor[2] as $valor) {
 $x .= $valor;
}


preg_match_all("/(\[\*\])(.*?)(\[\/\*\])/i", $x, $conteudo);

foreach($conteudo[2] as $valor) {
  echo "$valor<br/>";
}
?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

$txt = "[*]Italico[/*] xyz[*]Italico[/*]xyz[*]Italico[/*][*]Italico[/*] [*]Italico[/*]";
$new = preg_replace("#\[\*\](.+?)\[/\*\]#is", " <em>\\1</em> ", $txt);

echo "<strong>ORIGINAL:</strong> $txt<br /><strong>NOVO:</strong> $new";

Isto funciona para o que tu queres, penso eu...

Mas pelo que vi, tu estás a fazer listas de items tipo bbcode e o código que eu tenho para isso, é o seguinte:

$preg = array(
"#\[list\](\r\n)?(.+?)\[/list\]#is"      => "<ul>\\2</ul>",
"#\[list=(a|A|i|I|1)\](.+?)\[/list\]#is" => "<ol type=\"\\1\">\\2</ol>",
"#\[\*\](.+?)(\r|\[\*\])#"               => "<li>\\1</li>\\2",
"#</li>\[\*\](.+?)(\r|\[\*\])#"          => "<li>\\1</li>\\2",
"#(</li>\[\*\]|\[\*\])(.+?)</ul>#"       => "<li>\\2</li></ul>",
);

$str = "[list][*]Item 1[*]Item 2[*]Item 3[/list]";
$str = preg_replace(array_keys($preg), array_values($preg), $str);

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O teu 1º não funciona para o que quero, relativamente ao segundo é excelente :D

Só lhe vejo um defeito ;) É não permitir outro list dentro do list (como o BBCode permite).

Se adaptares o teu coloca aí que agradeço :D

Obrigado pelas ajudas :fixe

EDIT: Já agora isto parece-me falhar no teu código:

$str = "[list=1][*]Item 1[*]Item 2[*]Item 3[/list]";

O 3º aparece-me com * em vez de 3. :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O Nazgulled foi dormir porque tem exame amanhã, mas ele tava agora aqui ao meu lado e disse que amanhã te respondia...

EDIT: Já agora isto parece-me falhar no teu código:

$str = "[list=1][*]Item 1[*]Item 2[*]Item 3[/list]";

O 3º aparece-me com * em vez de 3. ;)

Isto não funciona para o primeiro ou segundo Código???

Tanto um como outro foram testados e funcionaram comigo.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

porque é que dizes que nao permite listas dentro de listas? o que é que acontece?

Eu nao domino regex, costumo ler documentação aqui e ali  qdo preciso. No entanto posso dar uma dica em relação a uma coisa que me lembro.

Neste tipo de situações e quando podem esta um 'objecto' dentro de outro 'objecto', cada vez que usas o metacaracter correspondente a uma ou mais ocorrencia de qualquer caracter, deves activar a opcao greedy ( por default está a off ) para encontrar a ocorrencia de menos comprimento. Isto faz-se com um ponto de interrogação a seguir ao metacaracter... assim sendo, cada vez que quiseres encontra "qq coisa aqui" usa:

.*?

Ja agora... n tenhas medo de usar software open source. Nestes casos costumo ir a http://phpxref.com , clico por exemplo num script de forums e uso o parser deles.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

@Bruno

Se tu explicasses exactamente o que queres fazer talvez fosse mais fácil te ajudar.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Pois explica melhor o que queres apanhar, porque se for 01,02,03 então:

0[123456789] deve servir.

Eu burro!!!

0[1-9]

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O Nazgulled foi dormir porque tem exame amanhã, mas ele tava agora aqui ao meu lado e disse que amanhã te respondia...

Ok ;)

EDIT: Já agora isto parece-me falhar no teu código:

$str = "[list=1][*]Item 1[*]Item 2[*]Item 3[/list]";

Isto não funciona para o primeiro ou segundo Código???

Tanto um como outro foram testados e funcionaram comigo.

Não funciona no 2º... o 3º dá-me asterisco em vez de "3.". De qq modo eu não preciso da funcionalidade de escolher o tipo de lista (se 1, a, A.... basta o dos * e isso eu consigo adaptar dali :P)

.*?

Ja agora... n tenhas medo de usar software open source. Nestes casos costumo ir a http://phpxref.com , clico por exemplo num script de forums e uso o parser deles.

Sim eu sei disso, mas eu não quero apanhar qq coisa, mas sim permitir apanhar a mm várias vezes. Eu conheço o software mas não me ajuda neste caso :D

@Bruno

Se tu explicasses exactamente o que queres fazer talvez fosse mais fácil te ajudar.

Eu quero interpretar o BBCode do list do forum...

Tem de começar e acabar com [list] (no que acaba tem de ter [/list]) e cada linha tem o [*] (caso simplifique pode acabar com [/*]).
E por fim, deverá permitir vários [list] dentro de outros, para tornar os efeitos assim:

  • Primeiro
  • Segundo
    • Segundo (1)
    • Segundo (2)
      • Segundo (3)(1)

    [*]Terceiro

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

não podias substituir o [ list ] por <ul>, o [ * ] por <li>, etc. directamente?

não sei quantos níveis de list's "encadadeados" tencionas permitir, mas se não houver limite, isso é impossível de fazer com ER's (a menos que as ER's do php sejam mais expressivas do que as matemáticas, o que duvido).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Não estou bem a entender o que não está a funcionar...

<?php
$preg = array(
"#\[list\](\r\n)?(.+?)\[/list\]#is"      => "<ul>\\2</ul>",
"#\[list=(a|A|i|I|1)\](.+?)\[/list\]#is" => "<ol type=\"\\1\">\\2</ol>",
"#\[\*\](.+?)(\r|\[\*\])#"               => "<li>\\1</li>\\2",
"#</li>\[\*\](.+?)(\r|\[\*\])#"          => "<li>\\1</li>\\2",
"#(</li>\[\*\]|\[\*\])(.+?)</ul>#"       => "<li>\\2</li></ul>",
);

$str = "[list][*]Item 1[*]Item 2[*]Item 3[/list]";
$str = preg_replace(array_keys($preg), array_values($preg), $str);
echo $str;
?>

Isto não funciona ai? É que aqui, apareceu tudo bem... Diz exactamente o que está a falhar que não estou a perceber. E tu queres ou não permitir lists dentro de lists?

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tive aqui a fazer isto, experimenta:

<?php

function GetLists($buffer) {
// NAO PERMITE SUBLISTAS
/*$preg = array(
	"#\[\*\](.+?)(\r\n|<li>|\[\*\]|\[/list\])#is" => "<li>\\1</li>\\2",
	"#\[\*\](.+?)(\r\n|<li>|\[/list\])#is"        => "<li>\\1</li>\\2",
	"#\[list\](.+?)\[/list\]#is"                  => "<ul>\\1</ul>",
	"#\[list=(a|A|i|I|1)\](.+?)\[/list\]#is"      => "<ol type=\"\\1\">\\2</ol>",
);*/

// PERMITE SUBLISTAS (APENAS 2 NIVEIS)
$preg = array(
	"#\[\*\](.+?)(\r\n|<li>|\[\*\]|\[/list\])#is" => "<li>\\1</li>\\2",
	"#\[\*\](.+?)(\r\n|<li>|\[/list\])#is"        => "<li>\\1</li>\\2",
	"#\[list\](.+?)\[/list\]#is"                  => "<ul>\\1</ul>",
	"#\[list\]</li>(.+?)\[/list\]#is"             => "<ul>\\1</ul>",
	"#\[list=(a|A|i|I|1)\](.+?)\[/list\]#is"      => "<ol type=\"\\1\">\\2</ol>",
	"#\[list=(a|A|i|I|1)\]</li>(.+?)\[/list\]#is" => "<ol type=\"\\1\">\\2</ol>",

);

return (preg_replace(array_keys($preg), array_values($preg), $buffer));
}

ob_start("GetLists");

?>
[list]
[*]Item 1
[*]Item 2
[*]Item 3
[*]Item 4
[/list]
<br />
[list]
[*]Item 1
[*]Item 2[list]
[*]Item 1
[*]Item 2
[*]Item 3
[*]Item 4
[/list]
[*]Item 3
[*]Item 4
[/list]
<br />
[list]
[*]Item 1[*] Item 2
[*] Item 3
[*]Item 4[/list]
<br />
[list][*]Item 1
[*]Item 2
[*]Item 3[*]Item 4
[/list]
<br />
[list][*]Item 1
[*]Item 2
[*]Item 3[list][*]Item 1
[*]Item 2
[*]Item 3[*]Item 4
[/list][*]Item 4
[/list]
<br />
[list][*]Item 1
[*]Item 2
[*]Item 3[*]Item 4[/list]
<br />
[list][*]Item 1[*]Item 2
[*]Item 3[*]Item 4
[/list]
<br />
[list][*]Item 1[*]Item 2[list][*] Item 1 [*] Item 2 [*] Item 3 [*] Item 4 [/list][*]Item 3[*]Item 4[/list]
<br />
[list][*] Item 1[*] Item 2[*]Item 3[*] Item 4[/list]
<br />
[list] [*] Item 1[*] Item 2[*]Item 3[*] Item 4[/list]
<br />
[list][*] Item 1[*] Item 2[*]Item 3[*] Item 4 [/list]
<br />
[list][*] Item 1 [*] Item 2[list][*]Item 1[*]Item 2[*]Item 3[*]Item 4[/list] [*] Item 3 [*] Item 4 [/list]
<br />
[list][*] Item 1 [*] Item 2 [*] Item 3 [*] Item 4 [/list]

<?php ob_end_flush(); ?>

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

É isto que não funciona:

bbcode.jpg

Relativamente ao teu ultimo código 5 estrelas :D Parece funcionar bem embora só dê os 2 níveis mas np, chega-me bem :)

Thk  :)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Hum,  em listas ordenadas, o ultimo não ta a dar é isso? Mas neste último código ja da? pelo menos aqui deste lado deu...

o código inicial que te dei já o fiz ha algum tempo e na altura testei muito superficialmente... este novo fiz durante a tarde... quanto aos niveis, tentei colocar mais, mas não estava a conseguir e já estava a ficar sem paciência, talvez mais tarde volte a tentar...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Eheh, realmente as expressões regulares tiram a paciência a qq gajo :)

Obrigado pelo código! Se depois fizeres algum update agradecia que o disponibilizasses :D

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora