correctement? - Retrouvez les réponses et les commentaires concernant cette question" />
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> </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> </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 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: Comment puis-je améliorer ce REGEX pour avoir un scénario où 5 et le nom de fichier 23456410321_a33456t604aec432567128ed10416ee. > <img src="/storage/USER_ID/articles/pictures/FILENAME">
" est remplacé par '?
5 Réponses :
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_IDetFILENAME.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'); } ?>
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
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> </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> </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";
}
([^\/]+\.[a-z]+)
src=".*?([^\/]+\.[a-z]+)?"
É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);
bien meilleure approche!
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
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"
$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'));
}
Passez à l'analyse HTML DOM, cela semble être le meilleur moment. Voir Comment analyser et traiter HTML / XML en PHP ?