correctement? - Retrouvez les réponses et les commentaires concernant cette question" />
2
votes

Regex - Comment puis-je obtenir ce modèle correctement?

J'ai un corps d'un message où l'utilisateur peut ou ne peut pas insérer une image. J'ai besoin de récupérer chaque occurrence de cette image sur le message. C'est le modèle:

preg_match_all ('/<img src=\"\/storage\/(.*?)\/articles\/pictures\/(.*?)\.(.*?)\"\>/g', $body , $result);

Disons donc que j'aurai ce corps:

$body = "... Cras ut tristique est. Etiam porttitor elit velit, vitae consequat eros interdum ac. Nam in blandit ante.</p><p>&nbsp;</p><figure class="image"><img src="/storage/5/articles/pictures/1560534410321_a363bc0d804aec432567128ed10416ee.jpeg"></figure><p>Integer sed justo accumsan, consequat nulla at, tincidunt massa. Integer orna Etiam porttitor elit velit, vitae consequat eros interdum ac. Nam in blandit ante.</p><p>&nbsp;</p><figure class="image"><img src="/storage/5/articles/pictures/23456410321_a33456t604aec432567128ed10416ee.jpeg"></figure> j hgfjhf  jfhfj hgf jh786 876 8 76fgj tfyt u  ufgi uyu y gi iy gygg ...";

Je veux récupérer le nombre 5 et le nom de fichier 1560534410321_a363bc0d804aec432567128ed10416ee.jpeg

et le numéro 5 et le nom de fichier 23456410321_a33456t604aec432567128ed10416ee. >

Donc, dans ce scénario, je pense que le modèle devrait être comme ceci: récupérer n'importe quel numéro et nom de fichier entre

Voici ce que je ont jusqu'à présent:

<img src="/storage/USER_ID/articles/pictures/FILENAME">

Comment puis-je améliorer ce REGEX pour avoir un scénario où " est remplacé par '?


1 commentaires

Passez à l'analyse HTML DOM, cela semble être le meilleur moment. Voir Comment analyser et traiter HTML / XML en PHP ?


5 Réponses :


2
votes

Vous devez utiliser l'analyse HTML DOM, puis REGEX .

DomDocument est un bon exemple de bibliothèque intégrée facile à configurer.

Vous pouvez utiliser ceci pour obtenir la valeur de chaîne de la propriété src d'une image:

<?php

$string = "/storage/5/articles/pictures/1560534410321_a363bc0d804aec432567128ed10416ee.jpeg";

// Perform Regex
$array = preg_match('\/storage\/(\d+)\/articles\/pictures\/((?:[\S\s])*)', $string);

$user_id = $array[1];
$filename = $array[2];

?>

Bien que cette bibliothèque soit assez limitée, elle gardera votre base de code petite et relativement efficace sans avoir à télécharger quoi que ce soit. :)

Après l'analyse du html, vous pouvez utiliser regex comme l'un des nombreux moyens d'obtenir les informations souhaitées à partir du chemin du fichier.

Ce qui suit expression regex fonctionnerait pour simplifier une chaîne dans les différentes parties de USER_ID et FILENAME.

DEMO

<?php

// Create a DOM object from a string
$dom = new DOMDocument;
$dom->loadHTML($string);

// Find all <img> with the id=foo attribute
$images = $dom->getElementsByTagName('img');

//Loop through all the images and print their 'src' tag
foreach ($images as $image) {
    echo $image->getAttribute('src');
}

?>

3 commentaires

Pas un DOM, mais une bibliothèque spéciale (et limitée).


Cette bibliothèque n'est pas recommandée. Sa base de code a plus d'une décennie. C'est désuet et fragile. De bien meilleures alternatives existent, en particulier DomDocument ou SimpleXML intégré à PHP.


Merci de me le faire savoir. @ miken32



-1
votes

Ici, nous utiliserions une expression simple avec preg_match_all:

1560534410321_a363bc0d804aec432567128ed10416ee.jpeg
23456410321_a33456t604aec432567128ed10416ee.jpeg

et la sortie souhaitée est dans ce groupe de capture:

$re = '/src=".*?([^\/]+\.[a-z]+)?"/m';
$str = '... Cras ut tristique est. Etiam porttitor elit velit, vitae consequat eros interdum ac. Nam in blandit ante.</p><p>&nbsp;</p><figure class="image"><img src="/storage/5/articles/pictures/1560534410321_a363bc0d804aec432567128ed10416ee.jpeg"></figure><p>Integer sed justo accumsan, consequat nulla at, tincidunt massa. Integer orna Etiam porttitor elit velit, vitae consequat eros interdum ac. Nam in blandit ante.</p><p>&nbsp;</p><figure class="image"><img src="/storage/5/articles/pictures/23456410321_a33456t604aec432567128ed10416ee.jpeg"></figure> j hgfjhf  jfhfj hgf jh786 876 8 76fgj tfyt u  ufgi uyu y gi iy gygg ...';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

foreach ($matches as $key => $value) {
    echo $value[1] . "\n";
}

Démo

Test h3>
([^\/]+\.[a-z]+)

Sortie

src=".*?([^\/]+\.[a-z]+)?"


0 commentaires

2
votes

Évitez d'analyser le HTML avec des expressions régulières.

Il vaut mieux d'abord restreindre les valeurs dont vous avez besoin, puis les appliquer si vous en avez besoin.

Array
(
    [0] => Array
        (
            [id] => 5
            [name] => 1560534410321_a363bc0d804aec432567128ed10416ee.jpeg
        )

    [1] => Array
        (
            [id] => 5
            [name] => 23456410321_a33456t604aec432567128ed10416ee.jpeg
        )

)

Résultat:

<?php
$body = '...';

$dom_err = libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHtml($body, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

$xpath = new DOMXPath($dom);

$imgs = [];
foreach ($xpath->query("//figure/img") as $img) {
    $src = $img->getAttribute('src');

    if (preg_match('#/storage/(.*)/articles/pictures/(.*)#', $src, $result)) {
        $imgs[] = [
            'id' => $result[1],
            'name' => $result[2]
        ];
    }
}

libxml_clear_errors();
libxml_use_internal_errors($dom_err);

print_r($imgs);

Démo


1 commentaires

bien meilleure approche!



0
votes

Cela fonctionne

"'] |" [^ "] *" |' [^ '] *') *? \ ssrc \ s * = \ s * (?: (['"]) (?: (?! \ 1) [\ S \ s]) *? / stockage / (\ d +) / articles / images / (( ?: (?! \ 1) [\ S \ s]) *) \ 1)) \ s + (?: "[\ S \ s] *?" | '[\ S \ s] *?' | [^ >] *?) +>

Le nombre est dans le groupe 2, le nom de fichier est dans le groupe 3.

https://regex101.com/r/4oSMXl/1

Expliqué

 # Begin open img tag

 < img
 (?= \s )
 (?=                    # Asserttion (a pseudo atomic group)
      (?: [^>"'] | " [^"]* " | ' [^']* ' )*?
      \s src \s* = \s*       # Src Attribute
      (?:
           ( ['"] )               # (1), Quote
           (?:                    # Src Value
                (?! \1 )
                [\S\s] 
           )*?

           /storage/
           ( \d+ )                # (2), Number
           /articles/pictures/

           (                      # (3 start), Filename, general to end of string
                (?:
                     (?! \1 )
                     [\S\s] 
                )*
           )                      # (3 end)
           \1                     # End Quote
      )
 )
                        # Have the code, just match the rest of tag
 \s+ 
 (?: " [\S\s]*? " | ' [\S\s]*? ' | [^>]*? )+

 >                      # End img tag


0 commentaires

0
votes

Voici deux points:

Si vous essayez d'extraire des informations de HTML / XML, utilisez l'analyseur correspondant. La plupart du temps, cela signifie DOM. Vous pouvez utiliser des expressions Xpath pour récupérer des nœuds. Ceci est limité au fait que PHP ne prend en charge que Xpath 1.0 et que cela signifie uniquement des fonctions de chaîne simples. Cependant, vous pouvez casser cela limite l'enregistrement et l'appel des fonctions PHP depuis Xpath.

array(2) { 
  [0]=> 
  string(3) "foo" 
  [1]=> 
  string(3) "bar" 
}

Sortie:

$pattern = '((?<quote>[\'"])(?<content>.*)?\g{quote})';
$subject = <<<'DATA'
'foo' "bar"
DATA;

preg_match_all($pattern, $subject, $matches);
var_dump($matches['content']);

C'est le meilleur façon. L'analyseur se chargera des spécificités du format comme les guillemets ou les entités de décodage.

Cependant, si vous aimez vraiment / avez besoin d'utiliser RegEx - un modèle PCRE correspondant à des caractères alternatifs est facile, utilisez simplement une classe de caractères comme (? ["']) ou un modèle alternatif comme (? " |') enveloppé dans un modèle nommé. Avec cela, vous pouvez le référencer pour un devis de clôture. Voici un exemple condensé:

string(43) "/storage/USER_ID/articles/pictures/FILENAME"

Sortie:

$html = <<<'HTML'
<img src="/storage/USER_ID/articles/pictures/FILENAME">
HTML;

$document = new DOMDocument();
$document->loadHTML($html);
$xpath = new DOMXpath($document);

$expression = '//img[starts-with(@src, "/storage/")]';

foreach ($xpath->evaluate($expression) as $imageNode) {
    var_dump($imageNode->getAttribute('src'));
}


0 commentaires