簡體   English   中英

用於錨標簽的PHP RegEx(或Alt方法)

[英]PHP RegEx (or Alt Method) for Anchor tags

好的,我必須解析一個SOAP請求,並在請求中將某些值與Anchor標記一起傳遞(或傳遞給內部)。 尋找正則表達式(或alt方法)以剝離標簽並僅返回值。

// But item needs to be a RegEx of some sort, it's a field right now
if($sObject->list == 'item') {
   // Split on > this should be the end of the right side of the anchor tag
   $pieces = explode(">", $sObject->fields->$field);

   // Split on < this should be the closing anchor tag
   $piece = explode("<", $pieces[1]);

   $fields_string .= $piece[0] . "\n";
}

item是一個字段名稱,但我想使其成為RegEx來檢查Anchor標簽,而不是特定字段。

PHP具有strip_tags()函數。

或者,您可以將filter_var()FILTER_SANITIZE_STRING

無論做什么,都不會使用正則表達式來解析HTML / XML。 這真的很容易出錯而且容易出錯。 PHP至少有3個不同的解析器作為標准(想到的是SimpleXMLDOMDocumentXMLReader )。

我同意cletus的觀點,在HTML上使用RegEx是不好的做法,因為HTML作為一種語言是多么的松散(我抱怨說PHP太松散了……)。 可以使用多種方法來更改標簽,除非您知道該文檔是符合標准/嚴格的文檔,否則有時是不可能的。 但是,由於我喜歡讓我分心的挑戰,因此您可以在RegEx中做到這一點!

我將其分成幾部分,如果您看到的只是一個字符串,然后說:“嗯...就可以了...”,這毫無意義! 首先,我們有一個錨標簽的主要RegEx:

'#<a></a>#'

然后,我們添加標簽之間的文本。 我們希望將其分組為括號,因此我們可以提取字符串,並且問號使星號通配符“ un-greedy”,這意味着它遇到的第一個</a>將是它用來結束正則表達式。

'#<a>(.*?)</a>#'

接下來,我們為Reg =“”添加RegEx。 我們將href="作為純文本進行匹配,然后匹配不包含引號的任意長度的字符串,然后匹配引號。

'#<a href\="([^"]*)">(.*?)</a>#'

現在我們只需要說標簽允許其他屬性。 根據規范,屬性可以包含以下字符: [a-zA-Z_\\:][a-zA-Z0-9_\\:\\.-]* 多次允許一個屬性,並使用一個值,我們得到: ( [a-zA-Z_\\:][a-zA-Z0-9_\\:\\.-]*\\="[^"]*")*

生成的RegEx(PCRE)如下:

'#<a( [a-zA-Z_\:][a-zA-Z0-9_\:\.-]*\="[^"]*")* href\="([^"]*)"( [a-zA-Z_\:][a-zA-Z0-9_\:\.-]*\="[^"]*")*>(.*?)</a>#'

現在,在PHP中,使用preg_match_all()函數可捕獲字符串中所有出現的事件。

$regex = '#<a( [a-zA-Z_\:][a-zA-Z0-9_\:\.-]*\="[^"]*")* href\="([^"]*)"( [a-zA-Z_\:][a-zA-Z0-9_\:\.-]*\="[^"]*")*>(.*?)</a>#';
preg_match_all($regex, $str_containing_anchors, $result);
foreach($result as $link)
 {
  $href = $link[2];
  $text = $link[4];
 }

使用simplexml和xpath檢索所需的節點

如果只想從特定標記中剝離或提取屬性,則應嘗試使用DOMDocument

像這樣:


$TagWhiteList = array(
    // Example of WhiteList
    'b', 'i', 'u', 'strong', 'em', 'a', 'img'
);

function getTextFromNode($Node, $Text = "") {
    // No tag, so it is a text
    if ($Node->tagName == null)
        return $Text.$Node->textContent;

    // You may select a tag here
    // Like:
    // if (in_array($TextName, $TagWhiteList)) 
    //     DoSomthingWithIt($Text,$Node);

    // Recursive to child
    $Node = $Node->firstChild;
    if ($Node != null)
        $Text = getTextFromNode($Node, $Text);

    // Recursive to sibling
    while($Node->nextSibling != null) {
        $Text = getTextFromNode($Node->nextSibling, $Text);
        $Node = $Node->nextSibling;
    }
    return $Text;
}

function getTextFromDocument($DOMDoc) {
    return getTextFromNode($DOMDoc->documentElement);
}

使用方法:


$Doc = new DOMDocument();
$Doc->loadHTMLFile("Test.html");

$Text = getTextFromDocument($Doc); echo "Text from HTML: ".$Text."\n";

上面的功能是如何剝離標簽。 但是您可以對其進行一些修改以操縱該元素。 例如,如果標記是Archor的“ a”,則可以提取其目標並顯示它而不是其中的文本。

希望能有所幫助。

如果您沒有某種request <-> class映射,則可以提取帶有DOM擴展名的信息。 屬性textConent包含上下文節點及其后代的所有文本。

$sr = '<?xml version="1.0"?>
<SOAP:Envelope xmlns:SOAP="urn:schemas-xmlsoap-org:soap.v1">
  <SOAP:Body>
    <foo:bar xmlns:foo="urn:yaddayadda">
       <fragment>
         <a href="....">Mary</a> had a
         little <a href="....">lamb</a>
       </fragment>
    </foo:bar>
  </SOAP:Body>
</SOAP:Envelope>';

$doc = new DOMDocument;
$doc->loadxml($sr);

$xpath = new DOMXPath($doc);
$ns = $xpath->query('//fragment');
if ( 0 < $ns->length ) {
  echo $ns->item(0)->nodeValue;
}

版畫

Mary had a
little lamb

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM