PHP Düzenli İfade - Bir Grup Maç Tekrarı

4 Cevap php

Ben böyle bir şey görünebilir bir dize var:

$r = 'Filed under: <a>Group1</a>, <a>Group2</a>';

İşte ben bugüne kadar kullanıyorum düzenli ifadedir:

preg_match_all("/Filed under: (?:<a.*?>([\w|\d|\s]+?)<\/a>)+?/", $r, $matches);

Ben içeriye normal ifadeyi istiyorum () sonunda +? ile belirlenmiş maçlar yapmaya devam etmek. Ama sadece bunu yapmayacağım. :: Sigh ::

Herhangi bir fikir. Ben bunun yerine kesiliyor normal bir ifadede bunu yapmanın bir yolu var olduğunu biliyorum.

4 Cevap

Deneyin:

<?php

$r = 'Filed under: <a>Group1</a>, <a>Group2</a>, <a>Group3</a>, <a>Group4</a>';

if(preg_match_all("/<a.*?>([^<]*?)<\/a>/", $r, $matches)) {
    var_dump($matches[1]); 
}

?>

çıktı:

array(4) {
  [0]=>
  string(6) "Group1"
  [1]=>
  string(6) "Group2"
  [2]=>
  string(6) "Group3"
  [3]=>
  string(6) "Group4"
}

EDIT:

Eğer benzersiz tespit maç için arama 'under' dizesini eklemek istediğiniz beri bunu preg_match tek bir çağrı kullanılarak yapılabilir eğer ben emin değilim, bu deneyebilirsiniz

// Since you want to match everything after 'Filed under'
if(preg_match("/Filed under:(.*)$/", $r, $matches)) {
    if(preg_match_all("/<a.*?>([^<]*?)<\/a>/", $matches[1], $matches)) {
        var_dump($matches[1]); 
    }
}

Sadece eğlence için burada çalışacak bir regex olan bir tek preg_match_all:

'%(?:Filed under:\s*+|\G</a>)[^<>]*+<a[^<>]*+>\K[^<>]*%`

Ya da, daha okunabilir bir biçimde:

'%(?:
      Filed under:   # your sentinel string
    |                
      \G             # NEXT MATCH POSITION
      </a>           # an end tag
  )
  [^<>]*+          # some non-tag stuff     
  <a[^<>]*+>       # an opening tag
  \K               # RESET MATCH START
  [^<>]+           # the tag's contents
%x'

\G Bir sonraki maç girişimi genellikle önceki başarılı maç sona erdi (ancak önceki maç sıfır uzunlukta ise, önümüzdeki bir daha darbe) nokta olan başlamak istiyorum konumunu eşleşir. İşte after en az bir kez Filed under: ile başlayan biri eşleşti olana kadar regex </a> ile başlayan bir alt dize maç olmayacak anlamına gelir.

Nöbetçi dize veya bir bitiş etiketi eşleşti sonra, [^<>]*+<a[^<>]*+> için her şeyi tüketir ve bir sonraki başlangıç ​​etiketi dahil. Maç (eğer varsa) <a> etiketi (bu olumlu Geriye İlerleme gibi, ama daha esnek) sonra başlamak görünür böylece daha sonra \K başlangıç ​​konumunu taklit. Son olarak, [^<>]+ etiketinin içeriğini eşleşir ve bitiş etiketi için maç konumunu getirir böylece \G eşleşebilir.

Ama dediğim gibi, bu sadece eğlence için olduğunu. Eğer have bir regex işi yapmak istemiyorsanız, kullandığınız codaddict @ gibi bir çok adım yaklaşım ile daha iyi; Bu, daha okunabilir, daha esnek ve daha rahat bulunuyor.

\K reference
\G reference

EDIT: Ben verdiği referanslar Perl dokümanlar için olsa da, bu özellikleri are da, PHP tarafından desteklenen - PCRE lib tarafından, daha doğru, ya da. Ben Perl docs biraz daha iyi olduğunu düşünüyorum, ama aynı zamanda PCRE manual bu şeyler okuyabilirsiniz.

Ben + ile belirlenmiş maçlar yapmaya devam etmek () içeriye düzenli ifade istiyorsun? sonunda.

+? tembel nicelik - bu sürede as few kez maç olacak. Diğer bir deyişle, sadece bir kez.

Eğer birkaç kez maç istiyorsanız, açgözlü bir nicelik istiyorum - +.

Ayrıca regex oldukça işe değil unutmayın - bunun için sorumluydu değil çünkü maç, en kısa sürede bu etiketleri arasına virgül karşılaştığında olarak başarısız olur. Bu da büyük ihtimalle düzeltme ihtiyacı vardır.

$r = 'Filed under: <a>Group1</a>, <a>Group2</a>'
$s = explode("</a>",$r);
foreach ($s as $k){
    if ($k){
        $k=explode("<a>",$k);
        print "$k[1]\n";
    }
}

çıktı

$ php test.php
Group1
Group2