Nasıl bir mektup ya da bir PHP preg_split stil regex birçok maç yapmak

5 Cevap php

Benim regex ile bir sorun yaşıyorum.

Ben <% bazı şeyler%> yakalamak istiyorum ve ben içinde ne gerekiyor <% ve%>

Bu regex bunun için oldukça iyi çalışıyor.

$matches = preg_split("/<%[\s]*(.*?)[\s]*%>/i",$markup,-1,(PREG_SPLIT_NO_EMPTY  |  PREG_SPLIT_DELIM_CAPTURE));

Ben de bazı şeyler% > yakalamak &% istiyorum yani <% veya < ve%%> veya% > yakalamak gerekiyor sırasıyla.

Ben Pars ikinci bir set koymak Eğer bayrak gördüğünüz gibi, ben Pars içinde ne yakalamaya çalışıyorum, çünkü (farklı preg_split işlevi yapar.

Tercihen, sadece < maç olur > için ve < için> de, ama bu tamamen gerekli değil

EDIT: KONU birden fazla maç içerebilir, ve ben hepsini gerekir

5 Cevap

Senin durumunda, onun ek bir parametre ve parantez preg_match kullanmak daha iyidir:

preg_match("#((?:<|&lt;)%)([\s]*(?:[^ø]*)[\s]*?)(%(?:>|&gt;))#i",$markup, $out);
print_r($out);

Array
(
    [0] => <% your stuff %>
    [1] => <%
    [2] => your stuff
    [3] => %>
)

Bu arada, PHP regexpi hata ayıklamak için bu online aracı kontrol, çok yararlı!

http://regex.larsolavtorvik.com/

EDIT: daha hızlı yüzden ben Regexp biraz kesmek. Bunu test, bu :-) çalışıyor

Şimdi tüm bu şeyler anlatalım:

  • preg_match o üçüncü param ($ burada out) olarak geçirilen var içinde yakalar her şeyi saklamak olacak
  • preg_match şey eşleşirse, dolar üzerinden saklamak olacak [0]
  • iç () değil (mi? :) desen şey $ üzerinden saklanır

Ayrıntılarda patten:

#((?:<|&lt;)%)([\s]*(?:[^ø]*)[\s]*?)(%(?:>|&gt;))#i can be viewed as ((?:<|&lt;)%) + ([\s]*(?:[^ø]*)[\s]*?) + (%(?:>|&gt;)).

((?:<|&lt;)%) is capturing < or &lt; then %
(%(?:>|&gt;)) is capturing % then < or &gt; 
([\s]*(?:[^ø]*)[\s]*?) means 0 or more spaces, then 0 or more times anything that is not the ø symbol, the 0 or more spaces.

Neden [^ ø] yerine kullanırım. ? Bu çünkü. çok zaman alıcı, regexp motoru, tüm varolan karakterler arasında kontrol edecektir. Karakter ø değilse [^ ø] sadece kontrol. Kimse bir uluslararası para sembolü, ø kullanır, ancak bakım varsa, (7) hangi besbelli bir web sayfasında yazdığınız asla oluyor kabuk çan char chr değiştirebilirsiniz.

EDIT2: Ben sadece tüm maçları yakalama hakkında okumak düzenlemek. Bu durumda, aynı şekilde preg_match_all kullanacağız.

<?php
$code = 'Here is a <% test %> and &lt;% another test %&gt; for you';
preg_match_all('/(<|&lt;)%\s*(.*?)\s*%(>|&gt;)/', $code, $matches);
print_r($matches[2]);
?>

Sonuç:

Array
(
    [0] => test
    [1] => another test
)

Gerçekten ne istediğinizi parantez içinde eşleşen ne ise neden preg_split kullanıyorsunuz? Sadece kullanımı basit olacak gibi görünüyor preg_match.

Genellikle Pars mantık gruplandırma için ve desenleri yakalamak için hem de kullanılan bu regex ile ilgili bir sorun var.

Regex sözdizimi PHP doc göre,

Düz parantez iki işlevi yerine getirmek her zaman yararlı değildir. Bir gruplama alt şablonu bir yakalama gereksinimi olmaksızın zamanlar genellikle vardır. Bir açma parantezi tarafından takip edilir ise: "?", Alt desenin herhangi bir yakalama yapmaz ve herhangi bir sonraki yakalayan alt şablonların sayısını hesaplarken sayılmaz.

Eğer vermek preg_match_all böyle bir düzenli ifade ile bir çekim için uygun istiyorsanız:

preg_match_all ('/ ((\ <\%) (\ s) (. *?) (\ s) (\%>)) / i', '<% wtf%> <% sadfdsafds%>', $ result);

Bu güneş altında hemen her şeyi bir maç sonuçları. Ekleyebilir / fazla / az maç Pars kaldırın:

Array ( [0] => Array ( [0] => <% wtf %> [1] => <% sadfdsafds %> )

[1] => Array
    (
        [0] => <% wtf %>
        [1] => <% sadfdsafds %>
    )

[2] => Array
    (
        [0] => <%
        [1] => <%
    )

[3] => Array
    (
        [0] =>  
        [1] =>  
    )

[4] => Array
    (
        [0] => wtf
        [1] => sadfdsafds
    )

[5] => Array
    (
        [0] =>  
        [1] =>  
    )

[6] => Array
    (
        [0] => %>
        [1] => %>
    )

)

Olası bir çözüm buradaki gibi, ekstra parens kullanımı, ancak sonuçlar, bu hendek, bu yüzden, toplam restults arasında gerçekte sadece use 1/2.

Bu regex

$matches = preg_split("/(<|&lt;)%[\s]*(.*?)[\s]*%(>|&gt;)/i",$markup,-1,(PREG_SPLIT_NO_EMPTY  |  PREG_SPLIT_DELIM_CAPTURE));

girişi için

Hi my name is <h1>Issac</h1><% some stuff %>here&lt;% more stuff %&gt;

çıkışı olacaktır

Array(
 [0]=>Hi my name is <h1>Issac</h1>
 [1]=><
 [2]=>some stuff
 [3]=>>
 [4]=>here
 [5]=>&;lt;
 [6]=>more stuff
 [7]=>&gt;
)

Ben sadece çift sayılar kullanılırsa, istenen resutls verecek olan