Considérez les éléments de tableau suivants
1.benclinton 2.clintonharry 3.harryben
Supposons que la liste de modèles est ben, harry, clinton , alors le résultat que je devrais obtenir est
1.benclinton 2.clintonharry 3.harryben 4.benwill 5.jasonsmith 6.smithclinton
Donc, essentiellement le résultat doit contenir des chaînes qui ne contiennent que les mots qui sont dans la liste des modèles. L'ordre n'est pas important
De plus, chaque chaîne n'aura pas plus de deux mots. c'est-à-dire que bensmith ne sera jamais un cas.
Puisque toutes mes chaînes sont dans un tableau, j'ai pensé à utiliser preg_grep en php pour faire cela, mais je suis frappé de cadrer correctement le regex pour cela.
quelle regex peut y parvenir? Existe-t-il un autre moyen efficace en dehors de la correspondance de regex qui fera le travail?
Merci d'avance!
3 Réponses :
Il semble que vous vouliez faire correspondre les éléments du tableau qui sont des combinaisons exactes de deux mots-clés. Pour une approche regex, nous pouvons essayer de prendre le produit croisé du vecteur de keyords, puis générer une alternance. Ensuite, nous pouvons utiliser preg_grep
contre votre tableau d'entrée pour trouver tous les éléments correspondants.
(benben|benharry|benclinton|harryben|harryharry|harryclinton|clintonben| clintonharry|clintonclinton)
Voici l'alternance regex générée par le script ci-dessus:
XXX
Merci. Existe-t-il un moyen sans utiliser la boucle for?
Sans Regex.Do avec array_filter
et strpos
<?php $a = ['benclinton','clintonharry','harryben','benwill','jasonsmith','smithclinton']; $a2 = ['ben','clinton','harry']; $res = array_filter($a,function($str="") use($a2){ $r =array_filter($a2,function($a2str) use($str){ return strpos($str,$a2str) !== FALSE; }); return count($r) > 1; }); print_r($res); ?>
Quelque chose comme ceci
$matches = preg_grep('/('.implode('|',array_map(function($name){return preg_quote($name,'/');},$names)).')(?1)/', $names_list);
Sortie
Array ( [0] => benclinton [1] => clintonharry [2] => harryben )
Cela nécessite qu'au moins deux des noms (même le même 2x) correspondent. Mais c'est un peu donné dans ce cas ou tout correspondrait.
Si vous voulez être très prudent, si les $ names
peuvent contenir quelque chose d'important pour l'expression régulière, comme +
, *
, \
etc. vous pouvez ajouter ceci
$names_list = ['benclinton','clintonharry','harryben','benwill','jasonsmith','smithclinton']; $names = ['ben','harry','clinton']; $matches = preg_grep('/('.implode('|',$names).')(?1)/', $names_list); //- /(ben|harry|clinton)(?1)/ -- (?1) = recurse capture group 1 print_r($matches);