PHP Regex Zorluk

6 Cevap php

Ben zorluk metin arasında boşluk ve satırbaşları olduğunda normal ifadeler yapıyorum yaşıyorum.

Örneğin, aşağıda bu durumda, nasıl "<div id="contentleft">" almak için düzenli ifade alabilirim?

<div id="content"> 


<div id="contentleft">  <SCRIPT language=JavaScript>

Denedim

id="content">(.*?)<SCRIPT

ama çalışmıyor.

6 Cevap

$s = '<div id="content">

<div id="contentleft">  <SCRIPT language=JavaScript>';

if( preg_match('/id="content">(.*?)<SCRIPT/s', $s, $matches) )
    print $matches[1]."\n";

Nokta, varsayılan olarak, satırsonlarının şeyi ama eşleşir. /s herşeyi maç yapar.

Ama gerçekten, bir DOM ayrıştırıcı kullanın. Sen ağaç yürüyebilir veya bir XPath sorgusu kullanabilirsiniz. XML için regexes gibi düşünün.

$s = '<div id="content">

<div id="contentleft">  <SCRIPT language=JavaScript>';

// Load the HTML
$doc = new DOMDocument();
$doc->loadHTML($s);

// Use XPath to find the <div id="content"> tag's descendants.
$xpath = new DOMXPath($doc);
$entries = $xpath->query("//div[@id='content']/descendant::*");

foreach( $nodes as $node ) {
    // Stop when we see <script ...>
    if( $node->nodeName == "script" )
        break;

    // do what you want with the content
}

XPath son derece güçlüdür. Here's some examples.

PS I Yukarıdaki kod bazı kadar sıkılır olabilir (umarım) eminim.

PCRE düzenleyiciler içine bir göz atın: http://ar2.php.net/manual/en/reference.pcre.pattern.modifiers.php

Sen dikkat et, rağmen şeklini değiştirir beri, ('/id="content">(.*?)<SCRIPT/s' gibi, s değiştirici uygulanır ^ ve çok $ çalışma. Olabilir

Aksi takdirde, yapabileceğiniz '/id="content">((.|\n)*?)<SCRIPT/'

EDIT: oops, yanlış değiştirici ...

Denemek

id="content">((?:.|\n)*?)<SCRIPT

Regex ile HTML ayrıştırmak için değil genel uyarı geçerlidir, ama sen zaten biliyorsun gibi görünüyor.

Alternatif olarak:

(?<=id="content">)(?:.|\n)*?(?=<SCRIPT)

Nokta varsayılan satır karakterleri eşleşmiyor. Etrafında almak için tek yolu, açıkça onları sağlamaktır. Eğer kullanmak için ne regex lezzet "dotall" değiştirici destek vermedi bile bu işe.

İlk regex vererek genişletilmiş yaklaşım, eşittir \n. Sizin maç grupta 1. olacağını, sadece bunu Döşeme gerekir.

İkinci regex başlayacak ve maçın sonunu işaretlemek için sıfır genişlik onaylamaları (look-ahead/look-behind) kullanır. Maç istemediğiniz şeyi, gerekli hiçbir gruplama içeremez.

Düzenli ifadeler olmadan başka bir çözüm:

$start = 'id="content">';
$end = '<SCRIPT';
if (($startPos = strpos($str, $start)) !== false &&
    ($endPos = strpos($str, $end, $startPos+1)) !== false) {
    $substr = substr($str, $startPos, $endPost-$startPos);
}

Eh, bu kadar desen düzenleyiciler bakmak çok çizgi konudur:

m (PCRE_MULTILINE) By default, PCRE treats the subject string as consisting of a single "line" of characters (even if it actually contains several newlines). The "start of line" metacharacter (^) matches only at the start of the string, while the "end of line" metacharacter ($) matches only at the end of the string, or before a terminating newline (unless D modifier is set). This is the same as Perl.

When this modifier is set, the "start of line" and "end of line" constructs match immediately following or immediately before any newline in the subject string, respectively, as well as at the very start and end. This is equivalent to Perl's /m modifier. If there are no "\n" characters in a subject string, or no occurrences of ^ or $ in a pattern, setting this modifier has no effect.

s (PCRE_DOTALL) If this modifier is set, a dot metacharacter in the pattern matches all characters, including newlines. Without it, newlines are excluded. This modifier is equivalent to Perl's /s modifier. A negative class such as [^a] always matches a newline character, independent of the setting of this modifier.

dan http://www.php.net/manual/en/reference.pcre.pattern.modifiers.php

$dom = new DOMDocument();
$dom->strictErrorChecking = false;
$dom->loadHTML($html_str);

$xpath = new DOMXPath($dom);
$div = $xpath->query('div[@id="content"]')->item(0);

Benim xpath ifade lütfen düzeltin - değil mi çalışacaktır eğer emin ...