RegEx kullanarak Özü formu alanları

1 Cevap php

Ben belirli bir URL ve form adı verilen bir sayfadaki tüm form girdilerini ve ilgili değerleri almak için bir yol arıyorum.

function GetForm($url, $name)
{
    return array
    (
    	'field_name_1' => 'value_1',
    	'field_name_2' => 'value_2',
    	'select_field_name' => array('option_1', 'option_2', 'option_3'),
    );
}

GetForm('http://www.google.com/', 'f');

Herkes bunu gerçekleştirmek için gerekli düzenli ifadeler bana sağlayabilir?

EDIT: Ben ancak ne arıyorum bana verilen bir formun tüm alanları almak için izin veren bir web sitesi agnostik bir çözümdür, DOM sorgulama çok daha güvenilir olacağını anlıyoruz. Ben bu ilk belge düğümleri bilmeden DOM ile mümkün olduğuna inanmıyorum, ben yanlış mıyım?

Ben şu RegEx'in ile geldim FORM etiketi için, bir kurşun geçirmez çözüm, standart web sayfalarında çalışan sadece bir şey gerekmez;

'~<form.*?name=[\'"]?' . $name . '[\'"]?.*?>(.+?)</form>~is'

Ben en zor seçenekte alanları için RegEx bulmak ne girdi alanları için benzer bir şey yapıyor zor olmayacaktır inanıyorum.

1 Cevap

HTML ayrıştırmak için regex kullanarak muhtemelen gitmek için en iyi yol değildir.

Eğer (bu biliyorsanız, örneğin, ve XPath sorguları) DOM yöntemlerini kullanarak bir HTML belgesi ile çalışmak sağlayacak DOMDocument::loadHTML okuyun, önceki sürebilir.

You might also want to take a look at Zend_Dom and Zend_Dom_Query, btw, which are quite nice if you can use some parts of Zend Framework in your application.
They are used to get fetch data from HTML pages when doing functionnal testing with Zend_Test, for instance -- and work quite well ;-)

Bazı HTML sayfaları karmaşa dikkate alınarak, ilk etapta zor görünebilir ... Ama olabilir, muhtemelen çok daha akıllıca bir fikir ...


EDIT after the comment and the edit of the OP

Burada "basit" bir şey, bir giriş etiketi tarafından başlamak üzere düşünce bir çift vardır:

  • birkaç satır genelinde yayılabilir
  • birçok nitelikleri olabilir
  • Sadece adını ve değerini size ilgi vardır condirering, bu iki olası sırayla olabilir gerçeği ile uğraşmak zorunda
  • nitelikleri çift tırnak, tek tırnak, ya da kendi değerleri etrafında bile hiçbir şey olabilir
  • etiketler / vasıflar küçük harf ya da büyük harf hem de olabilir
  • etiketleri her zaman kapalı olması gerekmez

Peki, bu noktalardan bazıları geçerli HTML değildir; ama yine de en avam web tarayıcılarda çalışır, bu yüzden dikkate alınması gereken ...

Only with those points, I wouldn't like to be the one writting the regex ^^
But I suppose there might be others difficulties I didn't think about.


On the other side, you have DOM and xpath... To get the value of an input name="q" (example is this page), it's a matter of something like this :

$url = 'http://www.google.fr/search?q=test&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a';
$html = file_get_contents($url);
$dom = new DOMDocument();
if (@$dom->loadHTML($html)) {
    // yep, not necessarily valid-html...
    $xpath = new DOMXpath($dom);

    $nodeList = $xpath->query('//input[@name="q"]');
    if ($nodeList->length > 0) {
        for ($i=0 ; $i<$nodeList->length ; $i++) {
            $node = $nodeList->item($i);
            var_dump($node->getAttribute('value'));
        }
    }

} else {
    // too bad...
}

What matters here ? The XPath query, and only that... And is there anything static/constant in it ?
Well, I say I want all <input> that have a name attribute that is equal to "q".
And it just works : I'm getting this result :

string 'test' (length=4)
string 'test' (length=4)

(I checked : there are two input name="q" on the page ^^ )

Do I know the structure of the page ? Absolutly not ;-)
I just know I/you/we want input tags named q ;-)

Ve biz ne olsun ;-)


EDIT 2 : and a bit fun with select and options :

Peki, sadece eğlence için, burada ben seçme ve seçenek için geldi ne:

$url = 'http://www.google.fr/language_tools?hl=fr';
$html = file_get_contents($url);
$dom = new DOMDocument();
if (@$dom->loadHTML($html)) {
    // yep, not necessarily valid-html...
    $xpath = new DOMXpath($dom);

    $nodeListSelects = $xpath->query('//select');
    if ($nodeListSelects->length > 0) {
        for ($i=0 ; $i<$nodeListSelects->length ; $i++) {
            $nodeSelect = $nodeListSelects->item($i);
            $name = $nodeSelect->getAttribute('name');
            $nodeListOptions = $xpath->query('option[@selected="selected"]', $nodeSelect);  // We want options that are inside the current select
            if ($nodeListOptions->length > 0) {
                for ($j=0 ; $j<$nodeListOptions->length ; $j++) {
                    $nodeOption = $nodeListOptions->item($j);
                    $value = $nodeOption->getAttribute('value');
                    var_dump("name='$name' => value='$value'");
                }
            }
        }
    }
} else {
    // too bad...
}

Ve ben bir çıkış olarak almak:

string 'name='sl' => value='fr'' (length=23)
string 'name='tl' => value='en'' (length=23)
string 'name='sl' => value='en'' (length=23)
string 'name='tl' => value='fr'' (length=23)
string 'name='sl' => value='en'' (length=23)
string 'name='tl' => value='fr'' (length=23)

Hangi beklediğim budur.

Bazı açıklamalar
?

Well, first of all, I get all the select tags of the page, and keep their name in memory.
Then, for each one of those, I get the selected option tags that are its descendants (there's always only one, btw).
And here, I have the value.

Önceki örnek ... Ama regex daha hala çok daha kolay, ben inanıyorum ki biraz daha karmaşık ... bana ... belki 10 dakika değil daha aldı Ve ben hala başlatmak için cesaret (delilik?) Olmaz -D: bunu yapmak mümkün olacaktır mutant regex çeşit hakkında thinkg

Oh, ve, bir dipnot düşmek gibi: ben hala gibi HTML belgesinin yapısı benzediğini hiçbir fikrim yok: ben bile tek bir göz almamış it ^ ^ kaynak bulunuyor


I hope this helps a bit more...
Who knows, maybe I'll convince you regex are not a good idea when it comes to parsing HTML... maybe ? ;-)

Hala: eğlenin!