Php Regex parenthèses

Eléphanteau du PHP | 21 Messages

04 déc. 2013, 14:01

Bonjour à tous,

je bute actuellement sur un problème de regex:

Voici un bout de mon texte que je veux tester:
'IFNULL(visit.date,NOW())'
Pour pouvoir récupérer 'visit.date' et 'NOW()' (qui sont en fait ajouté à la requête dynamiquement; il peut y avoir tout autre chose à la place).

Voici le regex que j'ai utilisé:
$sql = preg_replace_callback(
	'/IFNULL\((.+?),(.+?)\)/is',
	function ($matches){
		// 
	},
$sql);
Le problème est que ce pattern s'arrête dès la première parenthèse fermante qu'il trouve, ce qui n'est pas bon.
J'aimerais savoir comment faire pour omettre toutes les parenthèses contenu dans la parenthèse principale, sachant qu'il peut y avoir X niveaux de sous parenthèses ?
J'ai trouvé le pattern récursif sur google
'IFNULL\(((?>[^()]+)|(?R))*\)'
mais je ne sais pas si ça va faire exactement ce que je recherche et comment l'utiliser dans mon cas.

Auriez-vous une idée ?
Blog d'aide pour développeur web: http://www.yetaland.com

Petit nouveau ! | 5 Messages

07 déc. 2013, 10:03

Bonjour,

Je ne suis pas sûr d'avoir bien compris, il serait judicieux de mettre le résultat obtenu et celui attendu.

Voila ce que j'obtiens avec ta solution ( sql1 ) et la mienne ( sql 2) :

Code :
$sql0='IFNULL(visit.date,NOW())';
$sql=$sql0;echo "sql0=$sql<br>";
$sql=$sql0;$sql = preg_replace_callback('/IFNULL\((.+?),(.+?)\)/is',function ($matches){ },$sql);echo "sql1=$sql<br>";
$sql=$sql0;$sql = preg_replace_callback('/IFNULL\(.+?\)+/is',function ($matches){ },$sql);echo "sql2=$sql<br>";

Résultats :
sql0=IFNULL(visit.date,NOW())
sql1=)
sql2=

Eléphanteau du PHP | 21 Messages

09 déc. 2013, 11:31

Oui mais si tu fais ce code:
$sql0='IFNULL(visit.date,NOW())';
preg_replace_callback(
    '/IFNULL\((.+?),(.+?)\)/is',function ($matches){
        var_dump($matches);
        },$sql0);
Tu verras que l'on obtiens:
array(3) {
  [0]=>
  string(23) "IFNULL(visit.date,NOW()"
  [1]=>
  string(10) "visit.date"
  [2]=>
  string(4) "NOW("
}
Et en fait j'aimerais obtenir:
array(3) {
  [0]=>
  string(23) "IFNULL(visit.date,NOW())"
  [1]=>
  string(10) "visit.date"
  [2]=>
  string(4) "NOW()"
}
Blog d'aide pour développeur web: http://www.yetaland.com

Eléphanteau du PHP | 21 Messages

09 déc. 2013, 12:43

J'ai trouvé qu'en faisant ça:
$sql0='IFNULL(DATE(visit.date),NOW(test))';
$sql = preg_replace_callback(
'/\((([^()]*|(?R))*)\)/is',
function ($matches){
    $str = explode(',', $matches[1]);
    var_dump($str);
},
$sql0);
J'obtenais le résultat:
array(2) {
  [0]=>
  string(16) "DATE(visit.date)"
  [1]=>
  string(9) "NOW(test)"
}
Du coup ça pourrais être bon (en espérant qu'il n'y ai pas plusieurs virgules) sauf que ma regex ne prend pas en compte mon IFNULL du début :?
Blog d'aide pour développeur web: http://www.yetaland.com