Nos articles concernant les techniques web sont centrés sur des solutions pratiques qui mettent en œuvre, le plus souvent, notre framework web : Vae Soli!
Des articles généraux sont également fournis dans le respect des standards du web.
Tous nos articles web sont disponibles sous le couvert de la
licence
Creative Commons — Paternité - pas de modification.
2012-06-02 – 20:56
2012-06-02 – 20:56
2013-02-10 – 20:59
Voici un petit ensemble de 34 expressions régulières que vous pouvez utiliser dans votre code source afin de traiter un ensemble de petits problèmes de parsing. Vous avez le droit d'utiliser toutes les expressions régulières publiées sur cette page dans le respect de la licence Creative Commons - Attribution 3.0 non transposé (CC BY 3.0).
Dans nos exemples, le code HTML à parser, via l'expression régulière, se
trouve dans la variable $szHTML; les résultats trouvés par
utilisation de la regex sont mis dans un tableau dont le nom est
systématiquement $aMatch.
Si vous avez des remarques ou des suggestions, n'hésitez pas à les formuler grâce à la saisie de commentaires disponible dans le bas de l'article.
if ( preg_match( '/<!DOCTYPE +(.*?)>/si',$szHTML,$aMatch ) )
{
var_dump( $aMatch );
echo trim( $aMatch[1] );
}
$szHTML = preg_replace( '/<!DOCTYPE.*?>/si','',$szHTML );
if ( preg_match( '/<meta +http-equiv="content-type" +content="(.+?)" *\/>/si',$szHTML,$aMatch ) )
{
var_dump( $aMatch );
echo trim( $aMatch[1] );
}
if ( preg_match( '/<link +?rel=["\']canonical["\'] +?href=["\'](.+?)["\'].*?>/si',$szHTML,$aMatch ) )
{
var_dump( $aMatch );
echo trim( $aMatch[1] );
}
if ( preg_match_all( '%<h([1-6])[^>]*>(.*?)</h\1>%si',$szHTML,$aMatch,PREG_PATTERN_ORDER ) )
{
var_dump( $aMatch );
}
if ( preg_match( '/<meta +?http-equiv="content-language" +content="(.+?)" *\/>/si',$szHTML,$aMatch ) )
{
echo $aMatch[1];
}
elseif ( preg_match( '/<html +?lang="(.*?)".*?>/si',$szHTML,$aMatch ) )
{
echo $aMatch[1];
}
elseif ( preg_match( '/<html.+?xml:lang="(.*?)".*?>/si',$szHTML,$aMatch ) )
{
echo $aMatch[1];
}
elseif ( preg_match( '/<meta +?name=["\']DC\.language["\'] +?content=["\'](.*?)["\'] *?\/>/si',$szHTML,$aMatch ) )
{
echo $aMatch[1];
}
if ( preg_match_all( '%<a[^>]*href=(["\'])(.*?)\1[^>]*>.*?</a>%si',$szHTML,$aMatch,PREG_PATTERN_ORDER ) )
{
// Les href se trouvent dans $aMatch[2]
var_dump( $aMatch );
}
if ( preg_match( '%<title[^>]*>(.*?)</title>%si',$szHTML,$aMatch ) )
{
var_dump( $aMatch );
echo trim( $aMatch[1] );
}
if ( preg_match( '/<head[^>]*?>.*?<base.*?href="(.+?)".*?\/>.*?<\/head>/si',$szHTML,$aMatch ) )
{
var_dump( $aMatch );
echo trim( $aMatch[1] );
}
$szHTML = preg_replace( '%<script[^>]*>(.*?)</script>%si','',$szHTML );
$szHTML = preg_replace( '%<style[^>]*>(.*?)</style>%si','',$szHTML );
$szHTML = preg_replace( '%</?[a-z][a-z0-9]*[^<>]*>|<!--.*?-->%si','',$szHTML );
En fait, nous remplaçons les multiples occurrences d'une classe
spéciale : les whitespaces, c'est-à-dire les
espaces, les tabulations, les retours à la ligne. C'est à cela que
correspond la classe \s de l'expression régulière. Chaque
whitespace est remplacé par un seul espace.
$szHTML = preg_replace( '/\s{2,}/',' ',$szHTML ) );
$szHTML = preg_replace( '/[[:punct:]]/si','',$szHTML );
if ( preg_match( '/(19|20)[0-9]{2}(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])/',$szHTML ) )
{
echo 'I have a match'; // Case of 20120603
}
else
{
echo 'No match found'; // Case of 2012-06-03
}
if ( preg_match( '%([0-5][0-9])[0-9]{2}[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])%',$szHTML ) )
{
echo 'I have a match'; // Case of 2012-06-03, 2012 06 03, 2012/06/03, or 2012.06.03
}
else
{
echo 'No match found';
}
if ( preg_match( '/^<\?xml(.*)?\?>/',$szHTML,$aMatch ) )
{
echo 'XML';
var_dump( $aMatch );
}
else
{
echo 'No XML';
}
if ( preg_match( '/^%PDF/',$szHTML ) )
{
echo 'PDF';
}
if ( preg_match( '/^\xFF\xD8\xFF/',$szHTML ) )
{
echo 'JPG';
}
if ( preg_match( '/^\x89\x50\x4E\x47/',$szHTML ) )
{
echo 'PNG';
}
if ( preg_match( '/^\x47\x49\x46\x38[\x37\x39]\x61/',$szHTML ) )
{
echo 'GIF';
}
if ( preg_match( '/^\x50\x4B\x03\x04\x14\x00/',$szHTML ) )
{
echo 'ZIP';
}
if ( ( preg_match('/<script[^>]*>.*?google-analytics\.com\/ga\.js.*?<\/script>/si',$szHTML ) ) &&
( preg_match( '/["\'](UA-\d{6,9}-\d{1})["\']/si' ,$szHTML,$aMatch ) )
)
{
echo 'Google Analytics identifer: ' . $aMatch[1];
}
else
{
echo 'No Google Analytics found';
}
La variable testée, ici $szURL, équivaut typiquement à la valeur du href trouvée dans une balise <a>…</a> (doubles ou simples guillemets inclus dans la valeur du href).
if ( preg_match('/["\']javascript:[[:alnum:]]*?\((.*?)\).*?["\']/si',$szURL,$aMatch ) )
{
echo "Javascript detected in {$szURL}";
}
else
{
echo "No Javascript detected in {$szURL}";
}
La variable testée, ici $szURL, équivaut typiquement à la valeur du href trouvée dans une balise <a>…</a> dépouillée de ces simples ou doubles guillemets. On teste immédiatement si le début de la chaîne commence par 'javascript:'.
if ( preg_match('/^javascript:[[:alnum:]]*?\((.*?)\)/si',$this->szURL,$aMatch ) )
{
echo "Javascript detected in {$szURL}";
}
else
{
echo "No Javascript detected in {$szURL}";
}
function URL_Parse( $szURL )
/*------------------------*/
{
$aURL = array();
$aURL['path'] =
$aURL['domain'] =
$aURL['protocol'] = '';
if ( preg_match( '/\b((?P<protocol>http|https|ftp):\/\/)?(?P<domain>[-A-Z0-9.]+)(?P<path>\/[-A-Z0-9+&@#\/%=~_|!:,.;]*)?/i',$szURL,$aMatch ) )
{
$aURL['protocol'] = isset( $aMatch['protocol'] ) ? $aMatch['protocol'] : '';
$aURL['domain'] = isset( $aMatch['domain'] ) ? $aMatch['domain'] : '';
$aURL['path'] = isset( $aMatch['path'] ) ? $aMatch['path'] : '';
}
return ( $aURL );
}
function URL_ParseDomain( $szDomain )
/*---------------------------------*/
{
$aURL = array();
$aURL['tld'] =
$aURL['domain'] =
$aURL['subdomain'] = '';
if ( preg_match( '/(?P<subdomain>[[:alnum:]]+?)?\.(?P<domain>.+?)\.(?P<tld>.{2,})/i',$szDomain,$aMatch ) )
{
$aURL['subdomain'] = isset( $aMatch['subdomain'] ) ? $aMatch['subdomain'] : '';
$aURL['domain'] = isset( $aMatch['domain'] ) ? $aMatch['domain'] : '';
$aURL['tld'] = isset( $aMatch['tld'] ) ? $aMatch['tld'] : '';
}
return ( $aURL );
}
Cette expression régulière est un rien spéciale en ce qu'elle vérifie que
les différentes parts restent dans les limites possibles d'une heure : de 0
à 23 pour les heures, de 0 à 59 pour les minutes et les secondes. C'est
d'ailleurs sur base de cette expression régulière que nous avons créé la
fonction TIM_2Array() de Vae Soli! ci-dessous :
function TIM_2Array( $szTime,$szPart = null )
/*-----------------------------------------*/
{
$aParts = array(); /* Return value of the function */
$aParts['sec'] = /* Prepare associative array */
$aParts['min'] =
$aParts['hour'] =
'';
if ( preg_match( '/(?P<hour>0[0-9]|1[0-9]|2[0-3])(:??(?P<min>0[0-9]|[0-5][0-9])(:??(?P<sec>0[0-9]|[0-5][0-9]))?)?/',$szTime,$aMatch ) )
{
if ( isset( $aMatch['hour'] ) )
$aParts['hour'] = $aMatch['hour']; /* Hours */
if ( isset( $aMatch['min'] ) )
$aParts['min'] = $aMatch['min']; /* Minutes*/
if ( isset( $aMatch['sec'] ) )
$aParts['sec'] = $aMatch['sec']; /* Seconds */
}
if ( ! is_null( $szPart ) && isset( $aParts[$szPart] ) )
{
return ( $aParts[$szPart] ); /* Return part that is requested */
}
else
{
return ( $aParts ); /* Return result to caller */
}
}
Dans cet exemple, la variable testée est $szStr.
$szStr = "BE 0878.127.142";
if ( preg_match( '/BE *?(?P<vat>(0)?\d{3}\.??\d{3}\.??\d{3})/i',$szStr,$aMatch ) )
{
echo "<p>TVA = {$aMatch['vat']}</p>";
}
$szTag = quotemeta( $szTag ); /* Example 'h2' */
if ( preg_match_all( "/<{$szTag}[^>]*>(.*?)<\/{$szTag}>/si",$szHTML,$aMatch,PREG_PATTERN_ORDER ) )
{
var_dump( $aMatch );
}
geo.position)
if ( preg_match( '/<meta *?name=(["\'])geo\.position\1 *?content=(["\'])(?P<lat>\d{1,}?(\.\d{1,}?)?);(?P<long>\d{1,}?(\.\d{1,}?)?)\2.*?>/si',$this->szHTML,$aMatch ) )
{
echo $aMatch['lat'];
echo $aMatch['long'];
}
geo.placename et geo.region)
if ( preg_match( '/<meta *?name=(["\'])geo\.placename\1 *?content=(["\'])(?P<tag>.*?)\2.*?>/si',$this->szHTML,$aMatch ) )
{
echo trim( $aMatch['tag'] );
}
if ( preg_match( '/<meta *?name=(["\'])geo\.region\1 *?content=(["\'])(?P<tag>.*?)\2.*?>/si',$this->szHTML,$aMatch ) )
{
echo trim( $aMatch['tag'] );
}
ICBM)
if ( preg_match( '/<meta *?name=(["\'])ICBM\1 *?content=(["\'])(?P<lat>\d{1,}?(\.\d{1,}?)?),(?P<long>\d{1,}?(\.\d{1,}?)?)\2.*?>/si',$this->szHTML,$aMatch ) )
{
echo $aMatch['lat'];
echo $aMatch['long'];
}
float)
if ( preg_match( '/(?P<num>[+-]?\b[0-9]*\.?[0-9]+\b)/',$szHTML,$aMatch ) )
{
echo $aMatch['num'];
}
if ( preg_match_all( '/([[:alnum:]_]*?)=(["\'])(.*?)\2/i',$szTag,$aMatch,PREG_PATTERN_ORDER ) )
{
var_dump( $aMatch );
}