Regex per replace di un BBcode con parametri

skillsfactory

Utente Attivo
23 Nov 2012
50
0
0
salve ragazzi,
ho un bbcode che può avere diversi parametri (diciamo n parametri opzionali visto che è personalizzabile dall'utente). L'unico parametro che è sicuramente presente, perchè obbligatorio, è il parametro "id", per cui avro un codice di questo tipo:

Codice:
[bbcode param1='abc' param2='abc' id='IDCODE' param3='abc']testo opzionale etc.[/bbcode]

dovendo fare il replace di questo bbcode non riesco a scrivere una regola adatta a rimpiazzarlo tramite preg_replace().

ho provato ad esempio con:

PHP:
$testo = "questa è una stringa con bbcode [bbcode param1='abc' param2='abc' id='IDCODE' param3='abc']testo opzionale etc.[/bbcode]";
$id      = "IDCODE";
preg_replace("#\[bbcode(.*?)id='".$id."'(.*?)\](.*?)\[\/bbcode\]#",'è funziona perfettamente',$testo);

ovviamente non funziona... un altro tentativo è stato:
Codice:
#\[bbcode\s+id='".$chiave."'((.*?)!?\])(.*?)\[\/bbcode\]#

ma nulla...

vi ricordo le peculiarità del code:
- ha n parametri creati dall'utente
- ha sicuramente un parametro id di cui conosco il valore
- al suo interno è racchiuso del testo
- i valori dei parametri possono essere racchiusi sia tra apici ' ' che tra virgolette " "
- i prametri potrebbero essere separati da più spazi (vengono scritti dagli utenti e posso sbagliare)

qualche idea??? :)
 
Ultima modifica:

borgo italia

Super Moderatore
Membro dello Staff
SUPER MOD
MOD
4 Feb 2008
16.042
148
63
PR
www.borgo-italia.it
ciao
da quello che ho capito l'utente può fare quello che vuole, quindi secondo me più che una regex ti serve analizzare tutta la stringa.
io farei una funzione del tipo
PHP:
<?php
function analizza($testo){
	//riduci gli eventuali spazi in più
	$spazi=array("  ", "   ", "    ");//2, 3 , 4 spazi....
	$testo =str_replace($spazi, " ", $testo);
	//puoi toglere la chiusura tanto dovresti sapere che c'è e cosa è, eventualmente con un array come per gli spazi
	$testo =str_replace("[/bbcode]", "", $testo);
	$prima_dopo=explode("]",$testo);
	//$prima_dopo[1] conterrà il testo opzionale etc.
	//togli l'inizio del bbcode
	$prima_dopo[0]=str_replace("[bbcode", "", $prima_dopo[0]);
	//tolgo eventuali spazi sull =
	$uguale=array(' =','= ', ' = ');
	$prima_dopo[0]=str_replace($uguale, "=", $prima_dopo[0]);
	//tolgo eventuali spazi prima e dopo
	$prima_dopo[0]=trim($prima_dopo[0]);
	//estrai i parametri
	$parametri=explode(" ",$prima_dopo[0]);
	/*
	$parametri[0]=param1='abc'
	$parametri[1]=param2='abc'
	$parametri[2]=id='IDCODE'
	...ecc...
	*/
	//poi es se vuoi avere un array con nome parametro suo valore
	$par_array=array();
	$par_array[0]=$prima_dopo[1];
	foreach($parametri as $valore){
		$nome_val=explode("=",$valore);
		$par_array[$nome_val[0]]=$nome_val[1];
	}
	//poi dell'array ne fai quello che vuoi
	foreach($par_array as $chiave => $valore){
		if($valore ==""){//ripulisco di altri eventuali valori non validi
		/*potresti aggiungere se sai tutto l'elenco dei nomi dei parametri
		per ripulire da eventuali porcherie
		$nome=array('param1','param2',...ecc....);
		e nell' if aggiungere
		if($valore =="" || !in_array($chiave, $nome)){
		analogamente al posto di $valore =="" se sai quali valori puossono assumere i parametri
		if(!in_array($valore,$elenco) || !in_array($chiave, $nome)){
		*/
		unset($par_array[$chiave]);//elimino la porcheria
		}
	}
	return $par_array;
}
//..................
//test
$testo = "[bbcode param1='abc'   param2='abc'  id= 'IDCODE' param3='abc']testo opzionale etc.[/bbcode]";
$pulito=analizza($testo);
foreach($pulito as $ch => $val){
	echo "$ch: $val<br />";
}
?>
guarda che è un'idea da adattare alle tue esigenze
 

skillsfactory

Utente Attivo
23 Nov 2012
50
0
0
quella della funzione potrebbe essere una buona idea, tuttavia dovendo analizzare lunghe porzioni di codice ero orientato alla regex per avere un metodo molto più performante. Ti ringrazio cmq per la dritta! ;)

tuttavia la situazione è un pò più complessa e se hai giusto un altro minutino da dedicarmi, ti faccio un esempio pratico.

C'è un particolare bbcode che si chiama "traduci", composto da vari parametri tra cui l'id che corrisponde ad una chiave a cui corrisponde una traduzione per ogni lingua ed è più o meno formattato così (dico più o meno perchè l'utente potrebbe aggiungervi parametri).

Codice:
[traduci id="WELCOME_HOME" not="fr,de"]Benvenuto sul sito[/traduci]

l'id WELCOME_HOME dice al parser che deve sostituire "benvenuto sul sito" (o meglio tutto i bbcode) con la traduzione in lingua del visitatore salvata sotto la chiave WELCOME_HOME (le traduzioni sono in un db dove l'id è la chiave della tabella). il parametro "not" dice ad esempio che in francese (fr) e tedesco (de) quel messaggio non deve essere visualizzato (ma questo non è importante è giusto per capire che ci sono altri parametri).

La cosa importante è che il parser deve trovare quel tag, indipendentemente dalla sua formattazione (parametri, valori dei parametri opzionali, spazi in più etc.), sapendo che sicuramente c'è un id di cui conosco la chiave, e sostituirlo con la variante tradotta.

Banalmente per capirci, è come se dovessi fare questo:

PHP:
    $str = '[traduci id="WELCOME_HOME" not="fr,de"]benvenuto sul sito[/traduci]';
    echo str_replace('[traduci id="WELCOME_HOME" not="fr,de"]benvenuto sul sito[/traduci]','Welcome Site',$str);

ma senza dovermi preoccupare di avere la corrispondenza esatta.... quindi passare al metodo preg_replace con un espressione regolare è l'ideale, si tratta solo di scrivere bene la regola del tipo:

[traduci{qui ci può stare qualsiasi cosa}id="WELCOME_HOME"{qui ci può stare qualsiasi cosa}]{qui ci può stare qualsiasi cosa}[/traduci]

Ad esempio, se avessi questa situazione

PHP:
<?php
$str = '[traduci id=\'HELLO\']ciao[/traduci][traduci  id=\'HELLO\'   not=\'fr\' ]ciao[/traduci][traduci not="fr" id="HELLO"]ciao[/traduci][traduci   not="fr"   id="HELLO" param="abc"]ciao[/traduci]';

// traduco in francese
echo preg_replace("#\[traduci\s+id='HELLO'((.*?)!?\])(.*?)\[\/traduci\]#","SALUT",$str);
?>

otterrei come risultato (qui in opera: http://codepad.org/eI4FBzZO )

Codice:
SALUTSALUT[traduci not="fr" id="HELLO"]ciao[/traduci][traduci   not="fr"   id="HELLO"  param="abc"]ciao[/traduci]

cioè funziona ovviamente solo il primo e il secondo perchè rispettano la regola... a me semplicemente servirebbe una regola più snella, che funzioni in tutti e quattro i casi...
 
Ultima modifica:

skillsfactory

Utente Attivo
23 Nov 2012
50
0
0
come nn detto... soluzione trovata

PHP:
<?php
$chiavi = array('C1','C2','C3','C4','C5');

$str = '[traduci id=\'C1\']ciao[/traduci][traduci  id=\'C2\'   not=\'fr\' ]ciao[/traduci][traduci not="fr" id="C3"]ciao[/traduci][traduci   not="fr"   id="C4" param="abc"]ciao[/traduci][TRADUCI not="fr"  ONLY="sdcs"  id="C5" param="abc" dsfdsf="sdsf"]ciao[/traduci]';

// traduco in francese
foreach($chiavi as $chiave)
$str = preg_replace("#\[traduci(.*?)id=['|\"]".$chiave."['|\"](.*?)\](.*?)\[\/traduci\]#i","SALUT-".$chiave." | ",$str);

echo $str;
?>

http://codepad.org/8Nwtzr4B
 
Discussioni simili
Autore Titolo Forum Risposte Data
A Regex per isolare link interni con rel noopener PHP 0
K Come eliminare attributi regex per validazione con javascript Javascript 0
MarcoGrazia [Javascript] Regex per la validazione di un numero di telefono. Javascript 2
A Regex per estrapolare url da testo PHP 5
A Regex per domini .de PHP 2
L aiuto per questa semplice regex PHP 5
MarcoGrazia [PHP] [regex] Validare un url PHP 2
A [PHP] Blocco mail spam con regex PHP 2
otto9due [PHP] Dubbio esistenzaile: Regex email e stampa valori trovati.. PHP 5
Shyson Regex strana jQuery 0
MarcoGrazia [regex] validare un textbox con solo caratteri alfabetici. Javascript 6
G problema con regex PHP 0
Shyson Regex multipla PHP 0
S Regex ASP.NET 1
M RegEX ottenere testo tra due tag PHP 6
A haccess regex username PHP 11
A Regex array PHP 1
Shyson Regex accetta 2 volte il trattino Javascript 1
9 Estrarre Link da pagina web con una Regex Programmazione 0
SolidSnake4 regex convalida mail PHP 15
G Regex in PHP PHP 2
N Non Autorizzato. Dovresti rimuovere il parametro customize_messenger_channel per visualizzare l'anteprima in frontend. WordPress 1
P Aiuto per rendere un Bot Telegram Privato PHP 0
V Query per una somma PHP 2
A Tabella con bottoni per aggiornamento record PHP 6
G Consigli SEO per scrittura e struttura pagine SEO e Posizionamento 5
P Passare solo alcuni parametri a script per CSV PHP 0
A Consiglio per creazione sito web CMS (Content Management System) 0
L form immagini per il database PHP 0
S CREAZIONE DI SITO PER CORSI DI FORMAZIONE WordPress 1
I [cerchiamo][retribuito] Grafico/a per stickers Offerte e Richieste di Lavoro e/o Collaborazione 0
R Cercarsi programmatore per GDR PBC Offerte e Richieste di Lavoro e/o Collaborazione 0
L Sessione e array per utenti PHP 0
A Sottoquery con group by per mese MySQL 0
G Appicazione HTML per inserimento dai in Database Access Microsoft HTML e CSS 0
V [Cerco] Socio e Sviluppatore per App PlacesFinder Offerte e Richieste di Lavoro e/o Collaborazione 0
M user agent per il download di api PHP 0
B Stringa sql per ricerca su più campi Database 1
Cosina Upload multiplo con invio allegati per email PHP 0
P Editor per la realizzazione di siti HTML e CSS 1
M Versione nativa per M1. Photoshop 1
A Aiuto per pagina php PHP 0
M [Cerco] aiutanti per creare sito Offerte e Richieste di Lavoro e/o Collaborazione 8
T [cerco] scrittore/scrittrice per articoli web Offerte e Richieste di Lavoro e/o Collaborazione 5
L Interfaccia grafica per gestire sql server .NET Framework 1
B javascript per problemi con pdf e Safari Javascript 0
R Plugin per Gestire videocorsi a pagamento WordPress 3
Y Vorrei selezionare un colore di sfondo per una pagina web Javascript 0
C media per riga MySQL 1
I Cerca: blogger IT per articoli di prova Offerte e Richieste di Lavoro e/o Collaborazione 0

Discussioni simili