Regex match - can't work it out - php

I've got a string that I need to parse into an array in PHP. The string looks something like this:
(Key: ALL_HTTP)(Value:HTTP_HOST:10.1.1.1 )(Key: ALL_RAW)(Value:Host: 10.1.1.1:80 )(Key: APPL_MD_PATH)(Value:/ROOT)(Key: AUTH_TYPE)(Value:)(Key: AUTH_USER)(Value:)(Key: AUTH_PASSWORD)(Value:)(Key: LOGON_USER)(Value:)(Key: REMOTE_USER)(Value:)
The number of "key/value" pairs could be unlimited but is usually about 30-40 per string.
I've been playing with preg_match and a variation of an example from PHP.net - something like this:
preg_match('/(\S+): (\S+)/', $string, $result);
That gets me back the first key as $result[0] but doesn't help for the rest.
If anyone could help me with a proper expression that would be fantastic. I'd also appreciate any good reading resources for splitting strings with PCRE.
Thanks all!

Try something along the lines of
preg_match_all('/\(([^:)]+):\s*([^)]*)\)/',
"(Key: ALL_HTTP)(Value:HTTP_HOST:10.1.1.1 )(Key: ALL_RAW)(Value:Host: 10.1.1.1:80 )(Key: APPL_MD_PATH)(Value:/ROOT)(Key: AUTH_TYPE)(Value:)(Key: AUTH_USER)(Value:)(Key: AUTH_PASSWORD)(Value:)(Key: LOGON_USER)(Value:)(Key: REMOTE_USER)(Value:)",
$out, PREG_SET_ORDER);
foreach ($out as $pair) {
echo "ALL: ".$pair[0]."\n";
echo "KEY: ".$pair[1]."\n";
echo "VAL: ".$pair[2]."\n";
}
You probably don't need the ALL lines.
Based on your sample string, you might like this regex better:
'/\(Key: ([^)]+)\)\(Value:([^)]*)\)/'

The regular expression /\(Key:\s*(.*?)\)\(Value:\s*(.*?)\)/ will match all the key/value pairs in the string
This program builds an array $data with the each key/value pair related in an element
$str = '(Key: ALL_HTTP)(Value:HTTP_HOST:10.1.1.1 )(Key: ALL_RAW)(Value:Host: 10.1.1.1:80 )(Key: APPL_MD_PATH)(Value:/ROOT)(Key: AUTH_TYPE)(Value:)(Key: AUTH_USER)(Value:)(Key: AUTH_PASSWORD)(Value:)(Key: LOGON_USER)(Value:)(Key: REMOTE_USER)(Value:)';
$list = preg_match_all('/\(Key:\s*(.*?)\)\(Value:\s*(.*?)\)/', $str, $data);
$data = array_combine($data[1], $data[2]);
var_dump($data);
output
array(8) {
["ALL_HTTP"]=>
string(19) "HTTP_HOST:10.1.1.1 "
["ALL_RAW"]=>
string(18) "Host: 10.1.1.1:80 "
["APPL_MD_PATH"]=>
string(5) "/ROOT"
["AUTH_TYPE"]=>
string(0) ""
["AUTH_USER"]=>
string(0) ""
["AUTH_PASSWORD"]=>
string(0) ""
["LOGON_USER"]=>
string(0) ""
["REMOTE_USER"]=>
string(0) ""
}

Related

php5 copy sub-strings from string separated by space?

I am using php5 and have a script which will return IP addresses of the client.
Executing script using shell_exec() function. Now the output is like this: *192.168.10.40 192.168.10.41 *.
Now I need to store this in an array. I used preg_match() but it is not working.
Here is the code using preg_match() :
$test = shell_exec("/www/dhcp.sh");
$pattern='/([^ ]*) /';
preg_match($pattern, $test, $new);
preg_match() is returning 0;
Here is the one I used explode() :
$test = shell_exec("/www/dhcp.sh");
var_dump( explode(' ', $test ) );
I also used explode but I am getting the result as:
array(1) { [0]=> string(28) "192.168.10.40 192.168.10.41 " }
Can anyone tell me how can I split the string into an array?
Regards,
Sowmya
You can use explode to split your string:
explode(' ', '192.168.10.40 192.168.10.41'));
which gives you
array(2) {
[0]=>
string(13) "192.168.10.40"
[1]=>
string(13) "192.168.10.41"
}
http://php.net/manual/fr/function.explode.php

how can split the result set array to string in php

i need help. i was developed a page in smarty , i got a result set from a query and i need to change the result set to string and stored in text area
my query is given below
select val from test
my result set is print in var_dump in controller
{ [0]=> array(1) { ["val"]=> string(1) "c" } [1]=> array(1) { ["val"]=> string(3) "c++" } [2]=> array(1) { ["val"]=> string(4) "java" } [3]=> array(1) { ["val"]=> string(3) "PHP" } }
i need to change in to sting like c,c++,java,PHP
the changing function is preformed only controller
ple help me.. and thk adv
Use foreach for that. See more information here - http://php.net/manual/en/control-structures.foreach.php .
Example -
$array = Array("333", "222", "111");
foreach($array as $string) {
echo $string.'<br />';
}
Another solution would be to use implode.
See more information here - http://php.net/manual/en/function.implode.php and again a small example -
$array = Array("333", "222", "111");
$strings = implode(",", $array); // comma in first quotes are seperator, you can set it also to " " for a single space.
echo $strings; // In this case it will output 333,222,111 if you would set it to empty space then it would output 333 222 11
EDIT:
For writing in file you must use file functions.
Check this link - http://php.net/manual/en/function.file-put-contents.php
example -
// your file
$file = 'sample.txt';
$array = Array("333", "222", "111");
// Add all strings to $content.
foreach($array as $string) {
$content .= $string.'<br />';
}
// write everything in file
file_put_contents($file, $content);
Suggestion:
When you are writing SQL queries, I would suggest that you already now start learning to write them correctly, so they are easier to read.
For example, your query -
select val from test
Could be changed to -
SELECT `val` FROM `test`
which is alot easier to read and understand.
If You need to join all array with some delimeters, then use implode.
Example:
$arr = array("hi", "peter!", "how", "are", "you");
echo implode(" ", $arr) . "?";
//output
// hi peter! how are you?
If you want a string separated by commas, you must use the implode function
string implode ( string $glue , array $pieces )
glue: Defaults to an empty string. This is not the preferred usage of implode() as glue would be the second parameter and thus, the bad prototype would be used.
pieces:The array of strings to implode.
Returns a string containing a string representation of all the array elements in the same order, with the glue string between each element.
http://www.php.net/manual/en/function.implode.php
Example
$array = Array("333", "222", "111");
$string = explode(',', $array);
returns
"333,222,111"
if you want spaces:
$string = explode(' ', $array);
returns
"333 222 111"

Why preg_match fails to get the result?

I have the below text displayed on the browser and trying to get the URL from the string.
string 1 = voice-to-text from #switzerland: http://bit.ly/lnpDC12D
When I try to use preg_match and trying to get the URL, but it fails
$urlstr = "";
preg_match('/\b((?#protocol)https?|ftp):\/\/((?#domain)[-A-Z0-9.]+)((?#file)\/[-A-Z0-9+&##\/%=~_|!:,.;]*)?((?#parameters)\?[A-Z0-9+&##\/%
=~_|!:,.;]*)?/i', $urlstr, $match);
echo $match[0];
I think #switzerland: has one more http// ... will it be problem ?
the above split works perfect for the below string,
voice-to-text: http://bit.ly/jDcXrZg
In this case I think parse_url will be better choice than regex based code. Something like this may work (assuming your URL always starts with http):
$str = "voice-to-text from #switzerland: http://bit.ly/lnpDC12D";
$pos = strrpos($str, "http://");
if ($pos>=0) {
var_dump(parse_url(substr($str, $pos)));
}
OUTPUT
array(3) {
["scheme"]=>
string(4) "http"
["host"]=>
string(6) "bit.ly"
["path"]=>
string(9) "/lnpDC12D"
}
As far as I understand your request, here is a way to do it :
$str = 'voice-to-text from <a href="search.twitter.com/…;: http://bit.ly/lnpDC12D';
preg_match("~(bit.ly/\S+)~", $str, $m);
print_r($m);
output:
Array
(
[0] => bit.ly/lnpDC12D
[1] => bit.ly/lnpDC12D
)

PHP json-like-string split

I have this $str value :
[{\"firstname\":\"guest1\",\"lastname\":\"one\",\"age\":\"22\",\"gender\":\"Male\"},{\"firstname\":\"guest2\",\"lastname\":\"two\",\"age\":\"22\",\"gender\":\"Female\"}]
I want to split it into the following:
firstname:guest1,lastname:one,age:22
firstname:guest2,lastname:two,age:22
I tried explode (",",$str) , but it explode all using , as delimiter and I don't get what I want
anyone can help me ?
As Josh K points out, that looks suspiciously like a JSON string. Maybe you should do a json_decode() on it to get the actual data you're looking for, all organized nicely into an array of objects.
EDIT: it seems your string is itself wrapped in double quotes ", so you'll have to trim those away before you'll be able to decode it as valid JSON:
$str_json = trim($str, '"');
$guests = json_decode($str_json);
var_dump($guests);
I get this output with the var_dump(), so it's definitely valid JSON here:
array(2) {
[0]=>
object(stdClass)#1 (4) {
["firstname"]=>
string(6) "guest1"
["lastname"]=>
string(3) "one"
["age"]=>
string(2) "22"
["gender"]=>
string(4) "Male"
}
[1]=>
object(stdClass)#2 (4) {
["firstname"]=>
string(6) "guest2"
["lastname"]=>
string(3) "two"
["age"]=>
string(2) "22"
["gender"]=>
string(6) "Female"
}
}
JSON (JavaScript Object Notation) is not CSV (comma-separated values). They're two vastly different data formats, so you can't parse one like the other.
To get your two strings, use a loop to get the keys and values of each object, and then build the strings with those values:
foreach ($guests as $guest) {
$s = array();
foreach ($guest as $k => $v) {
if ($k == 'gender') break;
$s[] = "$k:$v";
}
echo implode(',', $s) . "\n";
}
Output:
firstname:guest1,lastname:one,age:22
firstname:guest2,lastname:two,age:22
(Assuming you do want to exclude the genders for whatever reason; if not, delete the if ($k == 'gender') break; line.)
If you split on ,'s then you will get all the other crap that surrounds it. You would then have to strip that off.
Looks a lot like JSON data to me, where is this string coming from?
If that is valid json, just run it through json_decode() to get a native php array...
Note that you may need to run it through stripslashes() first, as it appears you may have magic_quotes_gpc set... You can conditionally call it by checking with the function get_magic_quotes_gpc:
if (get_magic_quotes_gpc()) {
$_POST['foo'] = stripslashes($_POST['foo']);
}
$array = json_decode($_POST['foo']);
You need to use preg_replace function.
$ptn = "/,\\"gender\\":\\"\w+\\"\}\]?|\\"|\[?\{/";
$str = "[{\"firstname\":\"guest1\",\"lastname\":\"one\",\"age\":\"22\",\"gender\":\"Male\"},{\"firstname\":\"guest2\",\"lastname\":\"two\",\"age\":\"22\",\"gender\":\"Female\"}]";
$rpltxt = "";
echo preg_replace($ptn, $rpltxt, $str);
You can the php regular expression tester to test the result.
or use preg_match_all
$ptn = "/(firstname)\\":\\"(\w+)\\",\\"(lastname)\\":\\"(\w+)\\",\\"(age)\\":\\"(\d+)/";
$str = "[{\"firstname\":\"guest1\",\"lastname\":\"one\",\"age\":\"22\",\"gender\":\"Male\"},{\"firstname\":\"guest2\",\"lastname\":\"two\",\"age\":\"22\",\"gender\":\"Female\"}]";
preg_match_all($ptn, $str, $matches);
print_r($matches);
i still haven't get a chance to retrieve the JSON :
I var_dump the trimmed value as :
$str_json = trim($userdetails->other_guests, '"');
$guests = json_decode($str_json);
var_dump($str_json,$guests);
WHERE $userdetails->other_guests is the $str value I had before...
I get the following output :
string(169) "[{\"firstname\":\"guest1\",\"lastname\":\"one\",\"age\":\"22\",\"gender\":\"Male\"},{\"firstname\":\"guest2\",\"lastname\":\"two\",\"age\":\"23\",\"gender\":\"Female\"}]"
NULL
This mean the decoded json are NULL... strange

Regular expressions for Google operators

Using PHP, I'm trying to improve the search on my site by supporting Google like operators e.g.
keyword = natural/default
"keyword" or "search phrase" = exact match
keyword* = partial match
For this to work I need to to split the string into two arrays. One for the exact words (but without the double quotes) into $Array1() and put everything else (natural and partial keywords) into Array2().
What regular expressions would achieve this for the following string?
Example string ($string)
today i'm "trying" out a* "google search" "test"
Desired result
$Array1 = array(
[0]=>trying
[1]=>google search
[2]=>testing
);
$Array2 = array(
[0]=>today
[1]=>i'm
[2]=>out
[3]=>a*
);
1) Exact I've tried the following for the exact regexp but it returns two arrays, one with and one without the double quotes. I could just use $result[1] but there could be a trick that I'm missing here.
preg_match_all(
'/"([^"]+)"/iu',
'today i\'m "trying" \'out\' a* "google search" "test"',
$result
);
2) Natural/Partial The following rule returns the correct keywords, but along with several blank values. This regexp rule maybe sloppy or should I just run the array through array_filter()?
preg_split(
'/"([^"]+)"|(\s)/iu',
'today i\'m "trying" \'out\' a* "google search" "test"'
);
You can use strtok to tokenize the string.
See for example this tokenizeQuoted function derived from this tokenizedQuoted function in the comments on the strtok manual page:
// split a string into an array of space-delimited tokens, taking double-quoted and single-quoted strings into account
function tokenizeQuoted($string, $quotationMarks='"\'') {
$tokens = array(array(),array());
for ($nextToken=strtok($string, ' '); $nextToken!==false; $nextToken=strtok(' ')) {
if (strpos($quotationMarks, $nextToken[0]) !== false) {
if (strpos($quotationMarks, $nextToken[strlen($nextToken)-1]) !== false) {
$tokens[0][] = substr($nextToken, 1, -1);
} else {
$tokens[0][] = substr($nextToken, 1) . ' ' . strtok($nextToken[0]);
}
} else {
$tokens[1][] = $nextToken;
}
}
return $tokens;
}
Here’s an example of use:
$string = 'today i\'m "trying" out a* "google search" "test"';
var_dump(tokenizeQuoted($string));
The output:
array(2) {
[0]=>
array(3) {
[0]=>
string(6) "trying"
[1]=>
string(13) "google search"
[2]=>
string(4) "test"
}
[1]=>
array(4) {
[0]=>
string(5) "today"
[1]=>
string(3) "i'm"
[2]=>
string(3) "out"
[3]=>
string(2) "a*"
}
}

Categories