2017-02-20 6 views
1

Ich möchte die Zeichenkette durch Regex-Matching in PHP zu einem Dataset analysieren. Hier ist mein Code:preg_match_all gibt kein Ergebnis zurück.

$string = "?\t\t\t\t\t\t?\t\t\t\t\t\t\t\t\t\t\t\t<?xml version=\"1.0\" encoding=\"UTF-8\"?><documents><Resp><gatewayId>g10060<\/gatewayId><accountId>310198232<\/accountId><orderNo>0970980541000510490500480<\/orderNo><tId><\/tId><tAmt>20<\/tAmt><result>1<\/result><respCode>21<\/respCode><signMD5>7ecd1eb9b870aaba3bfa45892095194e<\/signMD5><\/Resp><\/documents>"; 
preg_match_all('/<(.*?)>(.*?)<\\/(.*?)>/', $string, $arr); 
echo json_encode($arr); 

aber es gibt mir nur [[],[],[],[]], als leere Arrays. Ich habe versucht, die Regex-Ausdruck auf https://regex101.com/, und es zeigt mir das korrekte Ergebnis, aber es funktioniert nicht auf meinem Server.

Was ich will, ist:

[ "gatewayId" => "g10060", 
    "accountId" => "310198232", 
    "orderNo" => "0970980541000510490500480", 
    "tId" => "", 
    "tAmt" => "20", 
    "result" => "1", 
    "respCode" => "21", 
    "signMD5" => "7ecd1eb9b870aaba3bfa45892095194e" ] 

Wie kann ich dieses Problem beheben?

+2

nicht reguläre Ausdrücke verwenden: http://stackoverflow.com/ Fragen/3577641/how-do-you-parse-und-Prozess-html-xml-in-php – nogad

+0

sie geben mir ein seltsames Format ähnlich wie Xml, aber ich kann nicht einfach XML-Parser – user3711105

+2

verwenden, dass ** IS ** xml – nogad

Antwort

4

Verwendung:

<?php 

$string = "?\t\t\t\t\t\t?\t\t\t\t\t\t\t\t\t\t\t\t<?xml version=\"1.0\" encoding=\"UTF-8\"?><documents><Resp><gatewayId>g10060<\/gatewayId><accountId>310198232<\/accountId><orderNo>0970980541000510490500480<\/orderNo><tId><\/tId><tAmt>20<\/tAmt><result>1<\/result><respCode>21<\/respCode><signMD5>7ecd1eb9b870aaba3bfa45892095194e<\/signMD5><\/Resp><\/documents>"; 
preg_match_all('#<([^\?>]+)>([^<]+)<\\\/[^>]+>#', $string, $arr); 

list($_, $tags, $values)= $arr; 

// As @billynoah said it's much less code 
$result = array_combine($tags, $values); 

/* 
* Old inefficient code commented 
* 
$result = array_reduce(array_keys($tags), function($carry, $key) use ($tags, $values){ 
    $k = $tags[$key]; 
    $v = $values[$key]; 
    $carry[$k] = $v; 
    return $carry; 
},[]); 
*/ 

var_dump($result); 

Ergebnis:

array(7) { 
    ["gatewayId"] => string(6) "g10060" 
    ["accountId"] => string(9) "310198232" 
    ["orderNo"] => string(25) "0970980541000510490500480" 
    ["tAmt"]  => string(2) "20" 
    ["result"] => string(1) "1" 
    ["respCode"] => string(2) "21" 
    ["signMD5"] => string(32) "7ecd1eb9b870aaba3bfa45892095194e" 
} 
+0

Sie haben Recht - ich war nur auf die Slash-Problem behoben - das ist besser. – billynoah

+0

könnte ich vorschlagen, ersetzen Sie das ganze 'array_reduce()' Bit mit einfach: '$ Ergebnis = Array_combine ($ Tags, $ Werte);' – billynoah

+0

oh .. yep ..meine Schuld :) – Wizard

2

Zunächst ist Regex nicht die beste Lösung zum Parsen von XML-Strings. Ich denke mit SimpleXml wäre das viel einfacher.

$ object = neu SimpleXMLElement ($ xmlString);

Ich habe Ihre Kommentare gelesen. Wenn ich Sie wäre, würde ich versuchen, das XML zu bereinigen und es als XML zu verwenden. Sie werden sowieso in Kreisen enden, indem Sie die Regex-Regeln ändern, wenn sich etwas in der Antwort ändert. Trimmen, ersetzen make es ein gültiges XML oder .... vielleicht können Sie versuchen, das gültige XML direkt von der Quelle zu erhalten

+0

, die "nicht?" \ t \ t'' in meiner Zeichenfolge wird durch Ausnahme mit SimpleXMLElement. – user3711105

+0

obwohl ich das entfernen, scheitern alle '' <\/XXXX> '' immer noch in xml validator – user3711105

+0

@ user3711105: ist es zu kompliziert zu schreiben '$ xml = str_replace (" \/","/", trim ($ str," ? \ ""); '? –

3

Sie müssen den Backslash doppelt entkommen lassen. Es hilft auch, einen nicht-slash Begrenzer zur besseren Lesbarkeit zu verwenden:

preg_match_all('~<(.*?)>(.*?)<\\\/(.*?)>~', $string, $arr); 
+0

das hilft, danke – user3711105

+0

für den Datensatz, wenn Sie '/' als Trennzeichen verwenden möchten, müssen Sie tatsächlich 5 Backslashes für die gesamte Sequenz: 'preg_match_all ('/ <(.*?)> (. *?) <\\\\\/(.*?)> /', $ string, $ arr); '. Es ist ein bisschen absurd - daher würde ich einfach ein anderes Trennzeichen wählen. froh, dass es geholfen hat. – billynoah

+0

upvoted als erste akzeptierte Antwort zu kompensieren – Wizard

Verwandte Themen