2010-04-12 3 views
1

Je cherche un bon exemple d'utilisation d'expressions rationnelles en PHP pour «reverse engineering» d'une lettre type (avec un format connu, bien sûr) qui a été collée dans une boîte de texte multiligne et envoyée à un script pour traitement.Utiliser regex pour extraire des variables à partir d'une lettre type en texte brut?

Ainsi, par exemple, supposons ceci est l'entrée de texte simple d'origine (extrait d'un communiqué de presse USDA):

WASHINGTON, le 5 Avril 2010 - Nord Bison nord-américain Co-Op , un nouveau Rockford, ND, l'établissement rappelle environ 25 000 livres de têtes entières de boeuf contenant des langues qui peuvent ne pas avoir eu les amygdales complètement enlevés, ce qui est non conforme aux règlements qui exigent la suppression des amygdales des bovins de tous âges, Service de la sécurité des aliments et de l'inspection (FSIS) du Ministère de l'Agriculture des États-Unis a annoncé aujourd'hui.

Pour plus de clarté, les champs qui sont variables sont présentées ci-dessous:

[pr_city =] WASHINGTON, [pr_date =] 5 Avril, 2010 - [corp_name =] Nord Coopération américaine du bison, un [corp_city =] New Rockford, [corp_state =] ND, l'établissement rappelle environ [quantité =] 25.000 livres de [produit =] entiers têtes de boeuf contenant des langues qui peuvent ne pas avoir eu les amygdales complètement enlevé, ce qui est conforme aux règlements qui exigent [raison =] l'enlèvement des amygdales des bovins de tous les âges, Service de la sécurité des aliments et de l'inspection du ministère de l'Agriculture des États-Unis (FSIS) a annoncé aujourd'hui.

Comment pourrais-je extraire efficacement le contenu du

  • pr_city
  • pr_date
  • corp_name
  • corp_city
  • corp_state
  • quantité
  • produit
  • raison

champs de mon exemple?

Toute aide serait appréciée, merci.

+1

Je ne sais pas ce que l'utilisateur passe dans la zone de texte multiligne, le texte tel quel ou le texte avec déjà les symboles [pr_city =], [pr_date =]? Je demande parce que l'entrée en texte clair contient une sorte de séparateurs parmi les champs (comme [pr_city =], [pr_date =], ...) ou chaque champ doit être d'une longueur fixe, sinon je ne voir comment une expression rationnelle ou toute autre chose pourrait être capable d'identifier les différentes parties du texte en clair. –

+0

Je m'excuse si je n'étais pas clair - le premier bloc de texte serait l'ORIGINAL, et le deuxième bloc met en évidence les "variables". Merci – Yaaqov

Répondre

4

Eh bien, une expression régulière qui fonctionne sur votre exemple pourrait ressembler à ceci (les sauts de ligne introduites pour garder cette bête lisible, doivent être enlevés avant utilisation):

/^(?P<pr_city>[^,]+), (?P<pr_date>[^-]+) - (?P<corp_name>.*?), a 
(?P<corp_city>[^,]+), (?P<corp_state>[^,]+), establishment is 
recalling approximately (?P<amount>.*?) of (?P<product>.*?), 
which is not compliant with regulations that require (?P<reason>.*?), 
the U\.S\. Department of Agriculture\'s Food Safety and Inspection 
Service \(FSIS\) announced today\.$/ 

Ainsi, en PHP, vous pouvez faire

if (preg_match('/^(?P<pr_city>[^,]+), (?P<pr_date>[^-]+) - (?P<corp_name>.*?), a (?P<corp_city>[^,]+), (?P<corp_state>[^,]+), establishment is recalling approximately (?P<amount>.*?) of (?P<product>.*?), which is not compliant with regulations that require (?P<reason>.*?), the U\.S\. Department of Agriculture\'s Food Safety and Inspection Service \(FSIS\) announced today\.$/', $subject, $regs)) { 
    $prcity = $regs['pr_city']; 
    $prdate = $regs['pr_date']; 
    ... etc. 
} else { 
    $result = ""; 
} 

cela suppose deux choses, par exemple qu'il n'y a pas de sauts de ligne et que l'entrée est la chaîne entière (et non une chaîne plus grande à partir de laquelle cette partie doit être extraite de). J'ai essayé de faire des suppositions sur des valeurs juridiques qui ont du sens, mais il y a de fortes chances que d'autres contributions puissent briser cela. Donc, d'autres cas de test sont probablement nécessaires.

+0

Excellent. Merci pour le délai d'exécution rapide. Pourriez-vous décomposer les expressions suivantes? (? P [^,] +), (? P [^ -] +) - (? P . *?) - J'essaie toujours d'apprendre la regex. Très appréciée. – Yaaqov

+0

Bien sûr. '(? P ...)' indique un groupe de capture nommé, vous pouvez donc vous référer au nom d'une correspondance au lieu de son numéro. La syntaxe est plutôt incohérente entre les différentes expressions regex. '[^,] +' signifie "correspondre à un ou plusieurs caractères qui ne sont pas des virgules", et '. *?' signifie "correspondre à un nombre quelconque de caractères sauf les retours à la ligne, en essayant de faire correspondre le moins possible ". –

+0

Donne un sens - merci – Yaaqov

2

Si le texte qui l'entoure est constante, alors quelque chose comme ça regex partiel pourrait faire l'affaire:

preg_match('/^(.*?), (.*?)- (.*?), a (.*?), (.*?), establishment is recalling approximately (.*?), which is not compliant with regulations that require (.*?), the U.S. Department of Agriculture's Food Safety and Inspection Service (FSIS) announced today./', $text, $matches); 

$matches[1] = 'WASHINGTON'; 
$matches[2] = 'April 5, 2010'; 
$matches[3] = ... etc... 

Si le texte change autour, alors vous allez finir avec une tonne de faux appariements, pas de correspondance, etc ... Essentiellement, vous auriez besoin d'une IA pour analyser/comprendre les versions PR.

1

Éditez: Veuillez ne pas tenir compte de cette réponse folle, car les deux autres sont meilleurs. Je devrais probablement le supprimer, mais je le garde pour référence.

J'ai une idée folle qui pourrait fonctionner: construire une chaîne XML à partir de l'entrée en ajoutant des annotations, puis l'analyser. Il pourrait ressembler à ceci (complètement non testé) Code:

preg_replace('([^,]*), ([^-]*)- ...etc...', '<pr_city>\1</pr_city><pr_date>\2</pr_date> ...etc...'); 

le XML est Parsing après un processus inutilement compliqué qu'il vaut mieux laisser à la documentation PHP: http://www.php.net/manual/en/function.xml-parse.php.

Vous pouvez également envisager de le convertir en JSON avec cette méthode, puis en utilisant json_decode() pour l'analyser. Dans tous les cas, vous devez penser à ce qui se passe lorsque les symboles " et > apparaissent dans l'entrée.

Il peut être plus simple de faire correspondre et de supprimer une partie du texte à la fois.

+0

Merci - Je vais jeter un coup d'oeil à ce lien. – Yaaqov

Questions connexes