Parsing de fichiers / Filtrage de données
Fermé
ryko1820
Messages postés
1677
Date d'inscription
dimanche 28 avril 2013
Statut
Membre
Dernière intervention
15 août 2021
-
Modifié par ryko1820 le 4/01/2014 à 13:00
ryko1820 Messages postés 1677 Date d'inscription dimanche 28 avril 2013 Statut Membre Dernière intervention 15 août 2021 - 21 janv. 2014 à 18:40
ryko1820 Messages postés 1677 Date d'inscription dimanche 28 avril 2013 Statut Membre Dernière intervention 15 août 2021 - 21 janv. 2014 à 18:40
A voir également:
- Parsing de fichiers / Filtrage de données
- Explorateur de fichiers - Guide
- Supprimer les données de navigation - Guide
- Impossible de supprimer un fichier - Guide
- Reinstaller windows sans perte de données - Guide
- Wetransfer gratuit fichiers lourd - Guide
3 réponses
mpmp93
Messages postés
6648
Date d'inscription
mercredi 13 avril 2011
Statut
Membre
Dernière intervention
28 septembre 2015
1 340
5 janv. 2014 à 00:25
5 janv. 2014 à 00:25
Bonsoir,
Oui ya moyen....
C'est in_array qui fera tout.
A+
Oui ya moyen....
$exclusion = array('toto','tata','titi'.......les autres données.....)
$mot // la variable qui contient le mot à rechercher dans le tableau
if (in_array($mot, $exclusion)) {
echo "j'ai trouvé";
}
C'est in_array qui fera tout.
A+
ryko1820
Messages postés
1677
Date d'inscription
dimanche 28 avril 2013
Statut
Membre
Dernière intervention
15 août 2021
276
Modifié par ryko1820 le 19/01/2014 à 21:33
Modifié par ryko1820 le 19/01/2014 à 21:33
Hello,
J'ai fait d'autres trucs depuis, et là il fallait que je rafraîchisse un peu mes données, alors je me suis replongé la dedans, et voilà ce que ça donne finalement :
(je l'utilise en CLI alors je fais des echo pour logger les actions)
Un fichier PHP pour les exclusions héberge les tableaux pour les blacklist sensitive et case ignore :
J'exploite ça comme ça (n'hésitez pas à critiquer j'apprends) :
Maintenant que je peux gérer plus facilement les exclusions, j'arrive à un taux de filtrage de mes données tout à fait intéressant ... Même si 2/3 "bruits" par-ci, par-là peuvent encore pas être filtrés.
Çà doit être facilement adaptable en procédural.
You may stop me but you can't stop us all ;-)
J'ai fait d'autres trucs depuis, et là il fallait que je rafraîchisse un peu mes données, alors je me suis replongé la dedans, et voilà ce que ça donne finalement :
(je l'utilise en CLI alors je fais des echo pour logger les actions)
Un fichier PHP pour les exclusions héberge les tableaux pour les blacklist sensitive et case ignore :
/* * * * * * * * * * * * * * * * File exclusionsList.php * * Liste des exclusions case sensitive et case ignore * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ $caseIgnoreExclusions = array( 'tutu', 'toto', 'tata', 'titi'); $caseSensitiveExclusions = array( 'AeGT', 'GGBf', 'GOLD', 'GolD', 'WV');
J'exploite ça comme ça (n'hésitez pas à critiquer j'apprends) :
class Fileutil { private $caseIgnoreExclusions = array(); private $caseSensitiveExclusions = array(); private $needle; public function __construct() { include 'exclusionsList.php'; $this->caseIgnoreExclusions = $caseIgnoreExclusions; $this->caseSensitiveExclusions = $caseSensitiveExclusions; $this->needle = ""; } public function parseFile($fileSource,$fileDest) { $fHndlSource = fopen($fileSource,"r"); $fHndlDest = fopen($fileDest,"w"); $totalLine = 0; $totalWrote = 0; $blankLineCount = 0; while (!feof($fHndlSource)) { $line = fgets($fHndlSource); $totalLine++; /* ... plusieurs manipulations sans grand intérérêt sur les strings, les mots ... on découpes les phrases, les mots, ça str_replace et ça explode ... */ if (strlen($fileName)>1) //pour retirer ligne vides { // pour logs echo "Original sentence = ". trim($fileName) ." \n"; $add_nl = ""; // Boucle de traitement des exclusions $fileName = ""; for ($wordCount = 0; $wordCount < count($explodedLine) && $wordCount < 6;$wordCount++) //on ne garde que les 6 premiers mots de chaque string pour sa reconstruction { $this->needle = $explodedLine[$wordCount]; // C'EST ICI QUE CA SE PASSE !!! :-) if (count($this->ar_stripos($this->caseIgnoreExclusions))>0 || count($this->ar_strpos($this->caseSensitiveExclusions))>0) { // pour logs strlen($add_nl)>0 ? $add_str="" : $add_str = "\tRemoved word(s) : "; echo $add_str. $explodedLine[$wordCount] ." "; $add_nl = "\n"; } else { $fileName .= $explodedLine[$wordCount] ." "; } } echo $add_nl."Final sentence = ". trim($fileName) ." \n===========================================\n"; // ... etc ... Ecriture de mon fichier SQL ... } else { $blankLineCount++; } } fclose($fHndlSource); fclose($fHndlDest); } // LES 2 FONCTIONS QUI FONT LE BOULOT public function ar_stripos($haystack){ return array_filter(array_map(function($cbArg){ return stripos($this->needle , $cbArg); },$haystack),'is_int'); } public function ar_strpos($haystack){ return array_filter(array_map(function($cbArg){ return strpos($this->needle , $cbArg); },$haystack),'is_int'); } }
Maintenant que je peux gérer plus facilement les exclusions, j'arrive à un taux de filtrage de mes données tout à fait intéressant ... Même si 2/3 "bruits" par-ci, par-là peuvent encore pas être filtrés.
Çà doit être facilement adaptable en procédural.
You may stop me but you can't stop us all ;-)
ryko1820
Messages postés
1677
Date d'inscription
dimanche 28 avril 2013
Statut
Membre
Dernière intervention
15 août 2021
276
19 janv. 2014 à 20:54
19 janv. 2014 à 20:54
... et merci à ceux qui m'ont donné des pistes :-)
ryko1820
Messages postés
1677
Date d'inscription
dimanche 28 avril 2013
Statut
Membre
Dernière intervention
15 août 2021
276
19 janv. 2014 à 21:10
19 janv. 2014 à 21:10
J'arrivais pas a passer ma $explodedLine[$wordCount] à mes fonctions et surtout à la callback et j'avais pas envie de créer encore plus de fonctions (et puis je voulais essayer cette syntaxe :p ) alors j'ai créé une propriété "private $needle" pour pouvoir la voir de partout dans la classe, y compris dans les fonctions de callback.
Si quelqu'un s'y connait en portée de variable dans les callback ça m'intéresserait d'avoir son avis.
Si quelqu'un s'y connait en portée de variable dans les callback ça m'intéresserait d'avoir son avis.
ryko1820
Messages postés
1677
Date d'inscription
dimanche 28 avril 2013
Statut
Membre
Dernière intervention
15 août 2021
276
Modifié par ryko1820 le 19/01/2014 à 21:16
Modifié par ryko1820 le 19/01/2014 à 21:16
ryko1820
Messages postés
1677
Date d'inscription
dimanche 28 avril 2013
Statut
Membre
Dernière intervention
15 août 2021
276
19 janv. 2014 à 21:46
19 janv. 2014 à 21:46
Au final, sans la propriété pour needle :
Le sujet aurait pu aussi être stripos et strpos utilisant des array en arguments, (fonctions anonymes, array_filter, array_map).
avec les "use" dans les fonctions
Le sujet aurait pu aussi être stripos et strpos utilisant des array en arguments, (fonctions anonymes, array_filter, array_map).
if (count($this->ar_stripos($this->caseIgnoreExclusions,$explodedLine[$wordCount]))>0 || count($this->ar_strpos($this->caseSensitiveExclusions,$explodedLine[$wordCount]))>0) { // pour logs strlen($add_nl)>0 ? $add_str="" : $add_str = "\tRemoved word(s) : "; echo $add_str. $explodedLine[$wordCount] ." "; $add_nl = "\n"; } else { $fileName .= $explodedLine[$wordCount] ." "; }
avec les "use" dans les fonctions
public function ar_stripos($haystack,$needle){ return array_filter(array_map(function($cbArg) use ($needle){ return stripos($needle , $cbArg); },$haystack),'is_int'); } public function ar_strpos($haystack,$needle){ return array_filter(array_map(function($cbArg) use ($needle){ return strpos($needle , $cbArg); },$haystack),'is_int'); }
ryko1820
Messages postés
1677
Date d'inscription
dimanche 28 avril 2013
Statut
Membre
Dernière intervention
15 août 2021
276
Modifié par ryko1820 le 21/01/2014 à 12:27
Modifié par ryko1820 le 21/01/2014 à 12:27
En fait j'aimerais encore affiner le filtrage, ma blacklist contenant uniquement des mots entiers à exclure.
Exemple, lorsque la string '100' est soumise à la fonction 'ar_strpos' et que le mot '100' est bien dans la liste des exclusions, ok, mais par contre j'aimerais ne pas exclure '10000' qui lui devrait être conservé ...
hummm, je vais essayer d'intégrer un strlen ou un test d'égalité strstr stristr dans la fonction anonyme pour conditionner le return ...
D'ailleur stripos et strpos sont peut être pas les meilleurs candidats finalement ...
Exemple, lorsque la string '100' est soumise à la fonction 'ar_strpos' et que le mot '100' est bien dans la liste des exclusions, ok, mais par contre j'aimerais ne pas exclure '10000' qui lui devrait être conservé ...
hummm, je vais essayer d'intégrer un strlen ou un test d'égalité strstr stristr dans la fonction anonyme pour conditionner le return ...
D'ailleur stripos et strpos sont peut être pas les meilleurs candidats finalement ...
mpmp93
Messages postés
6648
Date d'inscription
mercredi 13 avril 2011
Statut
Membre
Dernière intervention
28 septembre 2015
1 340
Modifié par mpmp93 le 21/01/2014 à 13:25
Modifié par mpmp93 le 21/01/2014 à 13:25
Bonjour,
une phrase c'est des mots séparés par des 'espace's..... Si on utilise explode comme ceci:
$phrase = " le mot '100' est bien dans la liste des exclusions, ok, mais par contre j'aimerais ne pas exclure '10000' qui...";
si je l'explode en php
$mots est un tableau. Ensuite, faire des tests de ce genre
et je reconsitute la nouvelle phrase:
$nouvellePhrase = implode(' ', $mots);
qui sera: " le mot '' est bien dans la liste des exclusions, ok, mais par contre j'aimerais ne pas exclure '10000' qui..."
Prévoir un nettoyage de $phrase avant explode
Pour le if dans le foreach, utiliser in_array et un tableau des mots à exclure
....
une phrase c'est des mots séparés par des 'espace's..... Si on utilise explode comme ceci:
$phrase = " le mot '100' est bien dans la liste des exclusions, ok, mais par contre j'aimerais ne pas exclure '10000' qui...";
si je l'explode en php
$mots = explode(' ',$phrase);
$mots est un tableau. Ensuite, faire des tests de ce genre
foreach($mots AS $key => $mot) { if($mot=='100') { unset($mots[$key]); } }
et je reconsitute la nouvelle phrase:
$nouvellePhrase = implode(' ', $mots);
qui sera: " le mot '' est bien dans la liste des exclusions, ok, mais par contre j'aimerais ne pas exclure '10000' qui..."
Prévoir un nettoyage de $phrase avant explode
Pour le if dans le foreach, utiliser in_array et un tableau des mots à exclure
....
ryko1820
Messages postés
1677
Date d'inscription
dimanche 28 avril 2013
Statut
Membre
Dernière intervention
15 août 2021
276
21 janv. 2014 à 18:40
21 janv. 2014 à 18:40
oui, j'ai essayé, en plus in_array est super rapide, mais pour le coup il est trop strict, à l'arrivée ma blacklist devrait contenir plus d'entrées ... En tout cas en l'état, elle est a refaire :(
Je vais peut être devoir me résoudre à l'utiliser, quite à ne faire que du case sensitive et allonger la liste car à force de rajouter des trucs dans mes fonctions, le traitement dépasse la limite des 30 sec, et ça commence à devenir un peu trop.
c'est dommage parce qu'a part ce gros problème de perf. mes 2 fonctions faisaient exactement ce que je voulais :
Les fonctions :
:'(
En attendant je suis revenu à la version d'avant, car en fait je fais tout ça que pour un mot qui me pose problème alors en attendant d'avoir le courage de me replonger la dedans, je corrigerais à la main.
Je vais peut être devoir me résoudre à l'utiliser, quite à ne faire que du case sensitive et allonger la liste car à force de rajouter des trucs dans mes fonctions, le traitement dépasse la limite des 30 sec, et ça commence à devenir un peu trop.
c'est dommage parce qu'a part ce gros problème de perf. mes 2 fonctions faisaient exactement ce que je voulais :
for ($wordCount = 0; $wordCount < count($nameArr) && $wordCount < 6;$wordCount++) //on ne garde que les 6 premiers mots de chaque $nameArr { // si mot blacklisté trouvé count > 0 $isCaseIgnoreWordInBL = count($this->ar_strcasecmp($this->caseIgnoreExclusions,$nameArr[$wordCount])); $isCaseSensitiveWordInBL = count($this->ar_strcmp($this->caseSensitiveExclusions,$nameArr[$wordCount])); if ( $isCaseIgnoreWordInBL===0 || $isCaseSensitiveWordInBL===0) { $printName .= $nameArr[$wordCount] ." "; } }
Les fonctions :
public function ar_strcasecmp($haystack,$needle) { return array_filter(array_map(function($cbArg) use ($needle){ $result = strcasecmp(trim($needle) , trim($cbArg)); if ($result === 0){ return $result; } },$haystack),'is_int'); } public function ar_strcmp($haystack,$needle) { return array_filter(array_map(function($cbArg) use ($needle){ $result = strcmp(trim($needle) , trim($cbArg)); if ($result === 0){ return $result; } },$haystack),'is_int'); }
:'(
En attendant je suis revenu à la version d'avant, car en fait je fais tout ça que pour un mot qui me pose problème alors en attendant d'avoir le courage de me replonger la dedans, je corrigerais à la main.
Modifié par ryko1820 le 5/01/2014 à 08:41
J'essayerais de voir aussi si en matière de performance c'est mieux, mais comme ça, sans connaitre les performances de la fonction je dirais qu'en plus : "ça se pourrait" :-).
Enfin pour ce script qui n'est lancé qu'à l'initialisation de la bdd, les performances sont secondaires, les insert faits en base ensuite prennant eux, plusieurs secondes :p
.
J'aurais du plus travailler les fonctions des tableaux ...
Je ne sais pas si j'aurais d'autres réponses, mais je laisse le sujet ouvert pour l'instant, au cas ou ...
13 janv. 2014 à 12:42
Pas d'autres suggestions Messieurs ? :-)
13 janv. 2014 à 14:28
Modifié par ryko1820 le 13/01/2014 à 18:28
Par contre je peux peut être m'en inspirer pour ce que je veux faire ... Je verrais.