Question

Je suis en train de faire une regex pour prendre des données sur une table.

le code que j'ai maintenant:

<table>
   <tr>
     <td>quote1</td>
     <td>have you trying it off and on again ?</td>
   </tr>
   <tr>
     <td>quote65</td>
     <td>You wouldn't steal a helmet of a policeman</td>
   </tr>
</table>

Je veux remplacer par:

quote1: avez-vous l'essayer et rallumez

quote65: Vous ne volerais pas un casque d'un policier

le code que je l'ai déjà écrit ceci:

%<td>((?s).*?)</td>%

Mais maintenant je suis bloqué.

Était-ce utile?

La solution

regex de Tim fonctionne probablement, mais vous voudrez peut-être envisager d'utiliser la fonctionnalité DOM de PHP au lieu de regex, car il peut être plus fiable dans le traitement des changements mineurs dans le balisage.

Voir la méthode loadHTML

Autres conseils

Si vous voulez vraiment utiliser les expressions régulières (peut-être OK si vous êtes vraiment vraiment sûr que votre chaîne sera toujours formaté comme ça), ce quelque chose comme ça, dans votre cas:

$str = <<<A
<table>
   <tr>
     <td>quote1</td>
     <td>have you trying it off and on again ?</td>
   </tr>
   <tr>
     <td>quote65</td>
     <td>You wouldn't steal a helmet of a policeman</td>
   </tr>
</table>
A;

$matches = array();
preg_match_all('#<tr>\s+?<td>(.*?)</td>\s+?<td>(.*?)</td>\s+?</tr>#', $str, $matches);

var_dump($matches);

Quelques mots sur l'expression rationnelle:

  • <tr>
  • puis un certain nombre d'espaces
  • puis <td>
  • alors ce que vous voulez capturer
  • puis </td>
  • et même à nouveau
  • et enfin, </tr>

Et j'utilise:

  • ? dans le regex pour correspondre en mode non gourmand
  • preg_match_all pour obtenir tous les matches

Vous obtenez alors les résultats que vous voulez dans $matches[1] et $matches[2] (non $matches[0]) ; voici la sortie du var_dump je (je l'ai supprimer l'entrée 0, pour le rendre plus court) :

array
  0 => 
    ...
  1 => 
    array
      0 => string 'quote1' (length=6)
      1 => string 'quote65' (length=7)
  2 => 
    array
      0 => string 'have you trying it off and on again ?' (length=37)
      1 => string 'You wouldn't steal a helmet of a policeman' (length=42)

Ensuite, vous avez juste besoin de manipuler ce tableau, avec quelques chaînes concaténation ou similaires; par exemple, comme ceci:

$num = count($matches[1]);
for ($i=0 ; $i<$num ; $i++) {
    echo $matches[1][$i] . ':' . $matches[2][$i] . '<br />';
}

Et vous obtenez:

quote1:have you trying it off and on again ?
quote65:You wouldn't steal a helmet of a policeman

Remarque: vous devez ajouter des contrôles de sécurité (comme preg_match_all doit retourner vrai, le nombre doit être d'au moins 1, ...)

Comme une note de côté: en utilisant regex pour analyser HTML est généralement pas vraiment une bonne idée ; si vous pouvez utiliser un analyseur réel, il devrait être plus sûr moyen ...

Comme cela devrait être fait d'habitude, l'extraction de texte de HTML et d'autres langues non régulières avec un analyseur - regexes peut causer des problèmes ici. Mais si vous êtes certain de la structure de vos données, vous pouvez utiliser

%<td>((?s).*?)</td>\s*<td>((?s).*?)</td>%

pour trouver les deux morceaux de texte. \ 1:. \ 2 serait alors le remplacement

Si le texte ne peut pas couvrir plus d'une ligne, vous seriez plus en sécurité laissant tomber les bits (?s) ...

Ne pas utiliser regex, utilisez un analyseur HTML. Tels que le PHP simple HTML DOM Parser

Extraire le contenu de chaque <td>

    preg_match_all("%\<td((?s).*?)</td>%", $respose, $mathes);
    var_dump($mathes);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top