0

I need to open a JS file from PHP, to find a json var in this file, and convert it to a php array.

Right now I can't figure out which regex to use.

// get the js file
$file = file_get_contents ("http://pve.proxmox.com/pve2-api-doc/apidoc.js");

// extract the json content of var pveapi
if ( preg_match ( "#pveapi = ({[^}]*})#", $file, $infoJson ) ) {
    $arrJson = json_decode ( $infoJson [1], true );
}

// shows nothing so far :((
print_r($arrJson);

I have found few examples to do that, but none would work for me. Anyone with decent skills in regex could help me please ?

Ben

edit: added a part of the js file :

var pveapi = [
   {
      "info" : {
         "GET" : {
            "parameters" : {
               "additionalProperties" : 0
            },
            "permissions" : {
               "user" : "all"
            },
            "returns" : {
               "type" : "array",
               "items" : {
                  "type" : "object",
                  "properties" : {}
               },
               "links" : [
                  {
                     "rel" : "child",
                     "href" : "{name}"
                  }
               ]
            },
            "name" : "index",
            "method" : "GET",
            "description" : "Cluster index."
         }
      }
    }
];

Ext.onReady(function() { ... }
4
  • try "#pveapi\s*=\s*({[^}]*})#" Commented Feb 25, 2015 at 13:02
  • thanks for the answer, i tried but it's still the same, not matching. Commented Feb 25, 2015 at 13:13
  • "/pveapi\s*\=\s*([^Ext\.onReady]*)/" Commented Feb 25, 2015 at 13:31
  • if you know that the pveapi you need is the first instance of var pveapi = in your javascript, AND you know that the pveapi does not contain the string Ext.onReady , AND you know that right after the pveapi, there's a Ext.onReady , this should work ... unfortunately i think you'll need a full-fledged javascript interpreter to grab the code reliably Commented Feb 25, 2015 at 13:32

2 Answers 2

3

In this case, the end can be found by matching a semicolon at the end of a line:

if (preg_match('/^var pveapi = (.*?);$/ms', $js, $matches)) {
    $data = json_decode($matches[1]);
    print_r($data);
}
Sign up to request clarification or add additional context in comments.

5 Comments

thanks, this is exactly what i wanted - my account is too young to upvote, but I flagged it as resolved.
and when the pveapi DOES contain a semicolon somewhere? :p
@hanshenrik It may contain a semicolon, just not at the end of a line.
oh, didn't think about that. still not reliable unless you know the javascript is beautified though, i think~
@hanshenrik Yeah, it gets trickier if you can't rely on newlines not being part of string values :)
0

Per default the RegEx engine operates greedily on individual lines, so you'd have to tell it to do the opposite – the RegEx you seem to be looking for would be

#\spveapi\s*=\s*(.*?);\s*$#s

What it does is:

  • #
    Start the expression
  • \s
    Make sure the variable name is preceded by whitespace, so it's not part of a different variable name
  • pveapi
    Find the variable
  • \s*=\s*
    Make sure there's an equal sign with optional whitespace around it
  • (.*?);\s*$
    Get as few characters as possible before finding a semicolon – i.e. all characters until the first semicolon that is follow only by optional whitespace and a line ending
  • #ms
    End the expression and tell it to let . match line endings too and match $ to the ending of each line

2 Comments

thanks for the answer and the details, there is little typo in your answer in the last part, you meant #ms instead of #s.
Yeah, I saw that my answer could be more complete, so edited it to add the whitespace and line ending to the 'stop clause' and the m to use it ;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.