พยายามค้นหาลิงก์ในหน้า
regex ของฉันคือ:
/<a\s[^>]*href=(\"\'??)([^\"\' >]*?)[^>]*>(.*)<\/a>/
แต่ดูเหมือนจะล้มเหลวที่
<a title="this" href="that">what?</a>
ฉันจะเปลี่ยน regex เพื่อจัดการกับ href ที่ไม่ได้วางไว้ก่อนในแท็กได้อย่างไร
พยายามค้นหาลิงก์ในหน้า
regex ของฉันคือ:
/<a\s[^>]*href=(\"\'??)([^\"\' >]*?)[^>]*>(.*)<\/a>/
แต่ดูเหมือนจะล้มเหลวที่
<a title="this" href="that">what?</a>
ฉันจะเปลี่ยน regex เพื่อจัดการกับ href ที่ไม่ได้วางไว้ก่อนในแท็กได้อย่างไร
คำตอบ:
ความน่าเชื่อถือ Regex เพื่อใช้ HTML เป็นเรื่องยาก นี่คือวิธีดำเนินการกับDOM :
$dom = new DOMDocument;
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('a') as $node) {
echo $dom->saveHtml($node), PHP_EOL;
}
ข้างต้นจะค้นหาและส่งออก"outerHTML"ของA
องค์ประกอบทั้งหมดใน$html
สตริง
ในการรับค่าข้อความทั้งหมดของโหนดคุณต้องทำ
echo $node->nodeValue;
เพื่อตรวจสอบว่ามีhref
แอตทริบิวต์อยู่หรือไม่คุณสามารถทำได้
echo $node->hasAttribute( 'href' );
ที่จะได้รับhref
แอตทริบิวต์ที่คุณต้องการจะทำอย่างไร
echo $node->getAttribute( 'href' );
หากต้องการเปลี่ยนhref
แอตทริบิวต์ที่คุณต้องการจะทำอย่างไร
$node->setAttribute('href', 'something else');
การลบhref
แอตทริบิวต์ที่คุณต้องการจะทำอย่างไร
$node->removeAttribute('href');
คุณยังสามารถค้นหาhref
แอตทริบิวต์ได้โดยตรงด้วยXPath
$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
$nodes = $xpath->query('//a/@href');
foreach($nodes as $href) {
echo $href->nodeValue; // echo current attribute value
$href->nodeValue = 'new value'; // set new attribute value
$href->parentNode->removeAttribute('href'); // remove attribute
}
ดูเพิ่มเติมที่:
เกี่ยวกับเรื่องเล็กน้อย: ฉันแน่ใจว่ามันซ้ำกันและคุณสามารถหาคำตอบได้จากที่ไหนสักแห่งที่นี่
ฉันเห็นด้วยกับกอร์ดอนคุณต้องใช้โปรแกรมแยกวิเคราะห์ HTML เพื่อแยกวิเคราะห์ HTML แต่ถ้าคุณต้องการ regex จริงๆคุณสามารถลองสิ่งนี้:
/^<a.*?href=(["\'])(.*?)\1.*$/
สิ่งนี้จะจับคู่<a
ที่จุดเริ่มต้นของสตริงตามด้วยจำนวนอักขระใด ๆ (ไม่โลภ) .*?
จากนั้นhref=
ตามด้วยลิงก์ที่ล้อมรอบด้วยอย่างใดอย่างหนึ่ง"
หรือ'
$str = '<a title="this" href="that">what?</a>';
preg_match('/^<a.*?href=(["\'])(.*?)\1.*$/', $str, $m);
var_dump($m);
เอาท์พุท:
array(3) {
[0]=>
string(37) "<a title="this" href="that">what?</a>"
[1]=>
string(1) """
[2]=>
string(4) "that"
}
รูปแบบที่คุณต้องการค้นหาน่าจะเป็นรูปแบบจุดยึดลิงก์เช่น (บางอย่าง):
$regex_pattern = "/<a href=\"(.*)\">(.*)<\/a>/";
ทำไมคุณไม่จับคู่
"<a.*?href\s*=\s*['"](.*?)['"]"
<?php
$str = '<a title="this" href="that">what?</a>';
$res = array();
preg_match_all("/<a.*?href\s*=\s*['\"](.*?)['\"]/", $str, $res);
var_dump($res);
?>
แล้วก็
$ php test.php
array(2) {
[0]=>
array(1) {
[0]=>
string(27) "<a title="this" href="that""
}
[1]=>
array(1) {
[0]=>
string(4) "that"
}
}
ซึ่งได้ผล ฉันเพิ่งถอดวงเล็บปีกกาแรกออก
preg_match_all("/<a.*?href\s*=\s*['\"](.*?)['\"]/", $str, $res, PREG_SET_ORDER);
เพื่อจับค่า href ทั้งหมดในการใช้อย่างถูกต้องforeach($res as $key => $val){echo $val[1]}
สำหรับผู้ที่ยังไม่ได้รับโซลูชันที่ง่ายและรวดเร็วโดยใช้ SimpleXML
$a = new SimpleXMLElement('<a href="www.something.com">Click here</a>');
echo $a['href']; // will echo www.something.com
มันใช้งานได้สำหรับฉัน
ฉันไม่แน่ใจว่าคุณกำลังพยายามทำอะไรที่นี่ แต่ถ้าคุณกำลังพยายามตรวจสอบความถูกต้องของลิงก์ให้ดูที่ filter_var () ของ PHP
หากคุณต้องการใช้นิพจน์ทั่วไปจริงๆลองดูเครื่องมือนี้อาจช่วยได้: http://regex.larsolavtorvik.com/
ใช้ regex ของคุณฉันปรับเปลี่ยนเล็กน้อยเพื่อให้เหมาะกับความต้องการของคุณ
<a.*?href=("|')(.*?)("|').*?>(.*)<\/a>
ฉันขอแนะนำให้คุณใช้HTML Parser เป็นการส่วนตัว
แก้ไข: ทดสอบแล้ว
<a title="this" href="that">what?</a>
การทดสอบอย่างรวดเร็ว: <a\s+[^>]*href=(\"\'??)([^\1]+)(?:\1)>(.*)<\/a>
ดูเหมือนว่าจะทำเคล็ดลับโดยการจับคู่ครั้งที่ 1 คือ "หรือ" ครั้งที่สอง "ค่า href" "ที่" และครั้งที่สามคือ "อะไร"
เหตุผลที่ฉันทิ้งนัดแรกของ "/" ไว้ในนั้นคือคุณสามารถใช้มันเพื่ออ้างอิงกลับในภายหลังสำหรับการปิด "/" ดังนั้นมันก็เหมือนกัน
ดูตัวอย่างสดได้ที่: http://www.rubular.com/r/jsKyK2b6do
preg_match_all ("/ (] >) (. ?) (</ a) /", $ content, $ impmatches, PREG_SET_ORDER);
ได้รับการทดสอบและดึงแท็กทั้งหมดจากโค้ด html ใด ๆ
สิ่งต่อไปนี้ใช้ได้ผลสำหรับฉันและส่งคืนทั้งhref
และvalue
ของแท็กจุดยึด
preg_match_all("'\<a.*?href=\"(.*?)\".*?\>(.*?)\<\/a\>'si", $html, $match);
if($match) {
foreach($match[0] as $k => $e) {
$urls[] = array(
'anchor' => $e,
'href' => $match[1][$k],
'value' => $match[2][$k]
);
}
}
อาร์เรย์หลายมิติที่เรียกว่า$urls
มีอาร์เรย์ย่อยที่เชื่อมโยงซึ่งใช้งานง่าย