I currently have this code running. It is splitting the variable $json where there are },{ but it also removes these characters, but really I need the trailing and leading brackets for the json_decode function to work. I have created a work around, but was wondering if there is a more elegant solution?
<?php
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5},{"a":1,"b":2,"c":3,"d":4,"e":5}';
$individuals = preg_split('/},{/',$json);
$loop_count =1;
foreach($individuals as $object){
if($loop_count == 1){$object .='}';}
else{$object ="{".$object;}
print_r(json_decode($object));
echo '<br />';
$loop_count++;
}
?>
EDIT:
The $json variable is actually retrieved as a json object. An proper example would be
[{"id":"foo","row":1,"col":1,"height":4,"width":5},{"id":"bar","row":2,"col":3,"height":4,"width":5}]
As you (presumably) already know, the string you have to start with isn't valid json because of the comma and the two objects; it's basically two json strings with a comma between them.
You're trying to solve this by splitting them, but there's a much easier way to fix this:
The work-around is simply to turn the string into valid JSON by wrapping it in square brackets:
$json = '[' . $json . ']';
Voila. The string is now valid json, and will be parsed successfully with a single call to json_decode().
Hope that helps.
You can always add them again.
Try this:
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5},{"a":1,"b":2,"c":3,"d":4,"e":5}';
$individuals = preg_split('/},{/',$json);
foreach($individuals as $key=>$val)
$individuals[$key] = '{'.$val.'}';
Related
I working at PHP Project With PHP Version 7.0.13
I was dealing with JSON lately, I have a JSON file that needs to be decode to PHP but before I decode the JSON, I need to clean some abstract string inside the file that JSON obtained inside, to clean the string using substr() to get the JSON.
when i write the code, like this:
$jsonraw = "\"{ JSON should be here, later }\"";
$cutstart = strpos($jsonraw, "{");
$cutend = strrpos($jsonraw, "\"");
$jsonclean = substr($jsonraw, $cutstart, $cutend);
echo $jsonclean;
The output is like this
{ JSON should be here, later }
But when the string is like this
$jsonraw = "\"some abstract string to remove { JSON should be here, later }\"";
The output is became like this
{ JSON should be here, later }"
As we can see there was a quote symbol " at the last of the string, I was trying to decrement the $cutend, like this $jsonclean = substr($jsonraw, $cutstart, --$cutend); and this to $cutend-1
Any help, I appreciate.
Sorry for my bad English
You can use preg_match to get the json from that string:
$string = "some abstract string to remove { JSON should be here, later }";
preg_match('/\{.*\}/', $string, $match);
var_dump($match[0]);
the result would be:
string(30) "{ JSON should be here, later }"
As the third parameter is the length of the string, you need to say that the length is the end position minus the start position...
$jsonclean = substr($jsonraw, $cutstart, $cutend-$cutstart);
I want to parse some json response into php array, the problem is nginx push stream module response with not separated json string, is possible to parse this without using regex?
'{"id":1,"channel":"1","text":"Hello World!"}{"id":2,"channel":"1","text":"Hello World!"}{"id":2,"channel":"1","text":{"key_x": "value_x"}}'
Edit
The real issue was that nginx push-stream module send archive in stream, so thats why there is no separator between json data in my snippet.
$str = '{"id":1,"channel":"1","text":"Hello World!"}{"id":2,"channel":"1","text":"Hello World!"}{"id":2,"channel":"1","text":"Hello World!"}';
$str = str_replace('}{', '},{', $str);
$str = '[' . $str . ']';
print_r(json_decode($str));
https://3v4l.org/BNVTg
I dont think this is actually possible without either changing the output or use regex / str_replace.
If you have control over the output you should change the output to valid json:
{"data":[
{"id":1,"channel":"1","text":"Hello World!"},
{"id":2,"channel":"1","text":"Hello World!"},
{"id":2,"channel":"1","text":"Hello World!"}
]}
It you cant do this then you could try to use str_replace with explode:
$data = str_replace('}{', '}<should_be_absolut_unique>{');
foreach( explode('<should_be_absolut_unique>', $data) as $json ){
# json_decode($json)
}
This is of course very unsave and not guaranteed to work because you dont know if the string replace works correctly if you do not know the data that is send!
I am trying to use a License PHP System…
I will like to show the status of their license to the users.
The license Server gives me this:
name=Service_Name;nextduedate=2013-02-25;status=Active
I need to have separated the data like this:
$name = “Service_Name”;
$nextduedate = “2013-02-25”;
$status = “Active”;
I have 2 days tring to resolve this problem with preg_match_all but i cant :(
This is basically a query string if you replace ; with &. You can try parse_str() like this:
$string = 'name=Service_Name;nextduedate=2013-02-25;status=Active';
parse_str(str_replace(';', '&', $string));
echo $name; // Service_Name
echo $nextduedate; // 2013-02-25
echo $status; // Active
This can rather simply be solved without regex. The use of explode() will help you.
$str = "name=Service_Name;nextduedate=2013-02-25;status=Active";
$split = explode(";", $str);
$structure = array();
foreach ($split as $element) {
$element = explode("=", $element);
$$element[0] = $element[1];
}
var_dump($name);
Though I urge you to use an array instead. Far more readable than inventing variables that didn't exist and are not explicitly declared.
It sounds like you just want to break the text down into separate lines along the semicolons, add a dollar sign at the front and then add spaces and quotes. I'm not sure you can do that in one step with a regular expression (or at least I don't want to think about what that regular expression would look like), but you can do it over multiple steps.
Use preg_split() to split the string into an array along the
semicolons.
Loop over the array.
Use str_replace to replace each '=' with ' = "'.
Use string concatenation to add a $ to the front and a "; to the end of each string.
That should work, assuming your data doesn't include quotes, equal signs, semicolons, etc. within the data. If it does, you'll have to figure out the parsing rules for that.
I'm working with a third party API that receives several parameters which must be encoded like this:
text[]=Hello%20World&text[]=How%20are%20you?&html[]=<p>Just%20fine,%20thank%20you</p>
As you can see this API can accept multiple parameters for text, and also for HTML (not in the sample call).
I have used http_build_query to correctly build a query string for other APIs
$params['text'][] = 'Hello World';
$params['text'][] = 'How are you?';
$params['html'][] = '<p>Just fine, thank you</p>';
$http_query = http_build_query($params);
The problem with this approach is that it will build a query string with the numeric index:
text[0]=Hello%20World&text[1]=How%20are%20you?&html[0]=<p>Just%20fine,%20thank%20you</p>
unfortunately the API I'm working with doesn't like the numeric index and fails.
Is there any php function/class-method that can help me build a query like this quickly?
Thank you
I don't know a standard way to do it (I think there is no such way), but here's an ugly solution:
Since [] is encoded by http_build_query, you may generate string with indices and then replace them.
preg_replace('/(%5B)\d+(%5D=)/i', '$1$2', http_build_query($params));
I very much agree with the answer by RiaD, but you might run into some problems with this code (sorry I can't just make this a comment due to lack of rep).
First off, as far as I know http_build_query returns an urlencode()'d string, which means you won't have [ and ] but instead you'll have %5B and %5D.
Second, PHP's PCRE engine recognizes the '[' character as the beginning of a character class and not just as a simple '[' (PCRE Meta Characters). This may end up replacing ALL digits from your request with '[]'.
You'll more likely want something like this:
preg_replace('/\%5B\d+\%5D/', '%5B%5D', http_build_query($params));
In this case, you'll need to escape the % characters because those also have a special meaning. Provided you have a string with the actual brackets instead of the escapes, try this:
preg_replace('/\[\d+\]/', '[]', $http_query);
There doesn't seem to be a way to do this with http_build_query. Sorry. On the docs page though, someone has this:
function cr_post($a,$b=0,$c=0){
if (!is_array($a)) return false;
foreach ((array)$a as $k=>$v){
if ($c) $k=$b."[]"; elseif (is_int($k)) $k=$b.$k;
if (is_array($v)||is_object($v)) {
$r[]=cr_post($v,$k,1);continue;
}
$r[]=urlencode($k)."=" .urlencode($v);
}
return implode("&",$r);
}
$params['text'][] = 'Hello World';
$params['text'][] = 'How are you?';
$params['html'][] = '<p>Just fine, thank you</p>';
$str = cr_post($params);
echo $str;
I haven't tested it. If it doesn't work then you're going to have to roll your own. Maybe you can publish a github gist so other people can use it!
Try this:
$params['text'][] = 'Hello World';
$params['text'][] = 'How are you?';
$params['html'][] = '<p>Just fine, thank you</p>';
foreach ($params as $key => $value) {
foreach ($value as $key2 => $value2) {
$http_query.= $key . "[]=" . $value2 . "&";
}
}
$http_query = substr($http_query, 0, strlen($http_query)-1); // remove the last '&'
$http_query = str_replace(" ", "%20", $http_query); // manually encode spaces
echo $http_query;
I have a really long string in a certain pattern such as:
userAccountName: abc userCompany: xyz userEmail: a#xyz.com userAddress1: userAddress2: userAddress3: userTown: ...
and so on. This pattern repeats.
I need to find a way to process this string so that I have the values of userAccountName:, userCompany:, etc. (i.e. preferably in an associative array or some such convenient format).
Is there an easy way to do this or will I have to write my own logic to split this string up into different parts?
Simple regular expressions like this userAccountName:\s*(\w+)\s+ can be used to capture matches and then use the captured matches to create a data structure.
If you can arrange for the data to be formatted as it is in a URL (ie, var=data&var2=data2) then you could use parse_str, which does almost exactly what you want, I think. Some mangling of your input data would do this in a straightforward manner.
You might have to use regex or your own logic.
Are you guaranteed that the string ": " does not appear anywhere within the values themselves? If so, you possibly could use implode to split the string into an array of alternating keys and values. You'd then have to walk through this array and format it the way you want. Here's a rough (probably inefficient) example I threw together quickly:
<?php
$keysAndValuesArray = implode(': ', $dataString);
$firstKeyName = 'userAccountName';
$associativeDataArray = array();
$currentIndex = -1;
$numItems = count($keysAndValuesArray);
for($i=0;$i<$numItems;i+=2) {
if($keysAndValuesArray[$i] == $firstKeyName) {
$associativeDataArray[] = array();
++$currentIndex;
}
$associativeDataArray[$currentIndex][$keysAndValuesArray[$i]] = $keysAndValuesArray[$i+1];
}
var_dump($associativeDataArray);
If you can write a regexp (for my example I'm considering there're no semicolons in values), you can parse it with preg_split or preg_match_all like this:
<?php
$raw_data = "userAccountName: abc userCompany: xyz";
$raw_data .= " userEmail: a#xyz.com userAddress1: userAddress2: ";
$data = array();
// /([^:]*\s+)?/ part works because the regexp is "greedy"
if (preg_match_all('/([a-z0-9_]+):\s+([^:]*\s+)?/i', $raw_data,
$items, PREG_SET_ORDER)) {
foreach ($items as $item) {
$data[$item[1]] = $item[2];
}
print_r($data);
}
?>
If that's not the case, please describe the grammar of your string in a bit more detail.
PCRE is included in PHP and can respond to your needs using regexp like:
if ($c=preg_match_all ("/userAccountName: (<userAccountName>\w+) userCompany: (<userCompany>\w+) userEmail: /", $txt, $matches))
{
$userAccountName = $matches['userAccountName'];
$userCompany = $matches['userCompany'];
// and so on...
}
the most difficult is to get the good regexp for your needs.
you can have a look at http://txt2re.com for some help
I think the solution closest to what I was looking for, I found at http://www.justin-cook.com/wp/2006/03/31/php-parse-a-string-between-two-strings/. I hope this proves useful to someone else. Thanks everyone for all the suggested solutions.
If i were you, i'll try to convert the strings in a json format with some regexp.
Then, simply use Json.