Soruna neden html PHP regex, yanlış öncelemeli

6 Cevap php

I (.+?) kelimeleri aşağıdaki kaynağı ". I. İHTİYAÇ YALITIM" yalıtmak için kullanmaya çalışıyorum:

<strong>Label:</strong></font></td>
    <td valign="top" width="82%"> <font face="Arial" size="2"> 
      I. NEED. ISOLATION  </font> </td>

(.+?), ben bu yapabileceğini kullanarak:

$regex = '/stuff before(.+?)stuff after/';

ve bu html için, olurdu:

$regex = '/<strong>Label:</strong></font></td>
    <td valign="top" width="82%"> <font face="Arial" size="2"> 
      (.+?)  </font> </td>/';

ama bunun nedeni yanlış kaçan o kadar boğucu oluyor. Ben PHP büyük değilim. Birisi de bu gibi görünüyor html dayalı kaçış hangi karakterler tavsiye misiniz?

<strong>Label:</strong></font></td>
    <td valign="top" width="82%"> <font face="Arial" size="2"> 
      I. NEED. ISOLATION  </font> </td>

Note that I'm not trying to design a regex pattern. I already have the pattern nailed down with (.+?), sadece php üzerine tıkamak değil bu yüzden doğru html kaçmak için bilmek gerekir.

6 Cevap

Bkz this previous StackOverflow question.

O dedi, kaçan sorun, / regex sınırlandırmak için zaten es kullanarak konum beri regex ayrıştırıcı karıştırıyorsun içinde / karakter, kaynaklanmaktadır.

Oldukça düzenli değil ki - Her şeyden önce, gerçekten HTML "ayrıştırmak" için denemek için düzenli ifadeler kullanmamalısınız.

DOMDocument::loadHTML gibi bir şey ve bazı XPath sorgusu ile gidiş genellikle çok daha iyi bir çözümdür.


But, if you really want to go with a regex (and it seems you do, judging from your comments to other answers), I suppose you should not use / as
regex delimiter : there are too many slashed in HTML already -- it'll be an escaping hell, as you already noticed.

Örneğin, regex ayırıcı olarak # kullanabilirsiniz:

$str = <<<STR
<strong>Label:</strong></font></td>
    <td valign="top" width="82%"> <font face="Arial" size="2"> 
      I. NEED. ISOLATION  </font> </td>
STR;
$regex = '#<strong>Label:</strong></font></td>
    <td valign="top" width="82%"> <font face="Arial" size="2"> 
      (.+?)  </font> </td>#';
if (preg_match($regex, $str, $m)) {
  var_dump($m[1]);
}

Alacak:

string 'I. NEED. ISOLATION' (length=18)

Önerdiğiniz koduna göre ben değiştim tek şey regex ayraç Not ;-)


And, using a character that's not present in the HTML string, I don't have anything to escape -- especially, I don't have to escape all the /s -- which means the regex is far more easy to both write, read, and understand.

Eğer kullanıyorsanız PCRE regular expressions, sen ifadenin içinde delimiters kaçmak gerekir (sizin durumunuzda /):

'/<strong>Label:<\/strong><\/font><\/td>
<td valign="top" width="82%"> <font face="Arial" size="2"> 
  (.+?)  <\/font> <\/td>/'

Ama muhtemelen daha önemli: Düzenli ifadeler HTML ayrıştırma için uygun değildir. Daha iyi DOMDocument tarafından sağlanan gibi bir uygun HTML ayrıştırıcı kullanmak ve DOMXPath ile bunu sorgulamak.

$str=<<<EOF
<strong>Label:</strong></font></td>
    <td valign="top" width="82%"> <font face="Arial" size="2">
      I. NEED. ISOLATION  </font> </td>
EOF;

$s = explode("</font>",$str);
foreach($s as $k=>$v){
    if(strpos($v,'<font face="Arial" size="2">')){
        $t=explode('<font face="Arial" size="2">',$v);
        print trim($t[1])."\n";
    }
}

çıktı

$ php test.php
I. NEED. ISOLATION

Sizin için yapan bir funciton vardır. Bu preg_quote http://pl2.php.net/preg_quote adında oluyor

$regex = '/'.preg_quote('<strong>Label:</strong></font></td>
<td valign="top" width="82%"> <font face="Arial" size="2"> 
  ').'(.+?)'.preg_quote('  </font> </td>).'/';

Ayrıca harf duyarlılığı ve satır sonları ile dikkatli olmalıdır. Ben genellikle /(.+?)/is gibi görünüyorsun yani başa benim regexplerde bayraklar eklemek eğilimindedir

Nitekim olarak, hiçbir şey (tabii (.+?) hariç) bir regex özel bir anlamı vardır bu dizede var. Eğer regex sınırlayıcı olarak kullanarak çünkü / bir soruna neden olduğunu tek nedeni budur. Sadece ~, örneğin gibi, farklı bir sınırlayıcı seçmeniz gerekir:

$regex = '~<strong>Label:</strong></font></td>
    <td valign="top" width="82%"> <font face="Arial" size="2"> 
      (.+?)  </font> </td>~';