PHP explode then double loop - php

I am trying to split up a string to stay under the limit of 70 characters... however, when i do this, my loop just stop right when it gets the first 70 characters and it doesn't attempt to do the 2nd set. The reason I'm going this route and not use str_split is to keep the entire words so I don't send out messages with half of a word. If the 2nd split has less than 70 characters, please still send it out...any kind of help with this is greatly appreciated.
$message="A new powerful earthquake convulsed the traumatized nation of Nepal on Tuesday, leveling buildings already damaged by the devastating quake that killed thousands of people less than three weeks ago."
$msg = explode(' ',$message);
foreach($msg as $key) {
$keylen = strlen($key);
$msglen = $msglen + $keylen;
if($msglen<70) {
$msgs .=$key." ";
// $agi->verbose("$msgs");
} else {
$params = array(
'src' => '18009993355',
'dst' => $callerid,
'text' => $msgs,
'type' => 'sms',
);
// $agi->verbose("sending: $msgs");
$response = $p->send_message($params);
$msgs = "";
$msglen = 0;
}
}

<?php
$message = "A new powerful earthquake convulsed the traumatized nation of Nepal on Tuesday, leveling buildings already damaged by the devastating quake that killed thousands of people less than three weeks ago.";
define ("MAX_PACKET_SIZE", 70);
$msg = explode (' ',$message);
$indexes = array (0);
$actualSize = 0 ;
for ($i=0 ; $i<count($msg) ; $i++) {
if ($actualSize + strlen ($msg[$i]) <= MAX_PACKET_SIZE ) {
$actualSize += strlen ($msg[$i]);
if (($i+1) < count($msg)) {
$actualSize++;
}
}else {
$indexes[] = $i;
$actualSize = 0 ;
}
}
$indexes[] = count ($msg);
for ($i=1 ; $i<count($indexes) ; $i++) {
$temp = array_extract ($msg, $indexes[$i-1], $indexes[$i]);
var_dump(implode (' ', $temp));
$params = array ('src' => '18009993355',
'dst' => $callerid,
'text' => implode (' ', $temp) ,
'type' => 'sms');
// $agi->verbose("sending: $msgs");
$response = $p->send_message($params);
}
function array_extract ($array, $start, $stop) {
$temp = array();
for ($i=$start ; $i<$stop ; $i++) {
$temp[] = $array[$i];
}
return $temp;
}

What does $msg contain? If the first message contains 49 or less characters, whilst the second message contains another 50 characters, it will not send the second message, isn't that the point?
You could place some var_dumps here and there to debug it.

Related

how to split string and add additional strin to it

i have a string and i need to add some html tag at certain index of the string.
$comment_text = 'neethu and Dilnaz Patel  check this'
Array ( [start_index_key] => 0 [string_length] => 6 )
Array ( [start_index_key] => 11 [string_length] => 12 )
i need to split at start index key with long mentioned in string_length
expected final output is
$formattedText = '<span>#neethu</span> and <span>#Dilnaz Patel</span>  check this'
what should i do?
This is a very strict method that will break at the first change.
Do you have control over the creation of the string? If so, you can create a string with placeholders and fill the values.
Even though you can do this with regex:
$pattern = '/(.+[^ ])\s+and (.+[^ ])\s+check this/i';
$string = 'neehu and Dilnaz Patel check this';
$replace = preg_replace($pattern, '<b>#$\1</b> and <b>#$\2</b> check this', $string);
But this is still a very rigid solution.
If you can try creating a string with placeholders for the names. this will be much easier to manage and change in the future.
<?php
function my_replace($string,$array_break)
{
$break_open = array();
$break_close = array();
$start = 0;
foreach($array_break as $key => $val)
{
// for tag <span>
if($key % 2 == 0)
{
$start = $val;
$break_open[] = $val;
}
else
{
// for tag </span>
$break_close[] = $start + $val;
}
}
$result = array();
for($i=0;$i<strlen($string);$i++)
{
$current_char = $string[$i];
if(in_array($i,$break_open))
{
$result[] = "<span>".$current_char;
}
else if(in_array($i,$break_close))
{
$result[] = $current_char."</span>";
}
else
{
$result[] = $current_char;
}
}
return implode("",$result);
}
$comment_text = 'neethu and Dilnaz Patel check this';
$my_result = my_replace($comment_text,array(0,6,11,12));
var_dump($my_result);
Explaination:
Create array parameter with: The even index (0,2,4,6,8,...) would be start_index_key and The odd index (1,3,5,7,9,...) would be string_length
read every break point , and store it in $break_open and $break_close
create array $result for result.
Loop your string, add , add or dont add spann with break_point
Result:
string '<span>neethu </span>and <span>Dilnaz Patel </span> check this' (length=61)

PHP, regex and multi-level dashes and grouping together according to string occurrence

I have a string which looks like this:
15-02-01-0000
15-02-02-0000
15-02-03-0000
15-02-04-0000
15-02-05-0000
15-02-10-0000
15-02-10-9100
15-02-10-9101
15-15-81-0000
15-15-81-0024
So the expected output would be:
All account grouping separated by "-" dashes for example: 15-02-01-0000 there is 3 grouping
start with 15
start with 15-02
start with 15-02-01
So the expected output would be:
First it will show
15 --> All account start with "15"
15-02 --> All account start with "15-02"
15-02-01 -- All accounts start with "15-02-01"
15-02-01-0000
15-02-02 -- All accounts start with 15-02-02
15-02-02-0000
15-02-03 -- onwards like above
15-02-03-0000
15-02-04
15-02-04-0000
15-02-05
15-02-05-0000
15-02-10
15-02-10-0000
15-02-10-9100
15-02-10-9101
15-15
15-15-81
15-15-81-0000
15-15-81-0024
I tried to use substr:
$res = substr("15-15-81-0024",3,2);
if ($res == "15") {
} else if ($res < 10 && $res != 00) {
} else {
}
But not working to put grouping.
Could you please suggest any good way?
You can break each data by - and build the array in as much as needed. Notice the use of & in the code as using reference to result array.
Example:
$str = "15-02-01-0000,15-02-02-0000,15-02-03-0000,15-02-04-0000,15-02-05-0000,15-02-10-0000,15-02-10-9100,15-02-10-9101,15-15-81-0000,15-15-81-0024";
$arr = explode(",", $str);
$res = [];
foreach($arr as $e) { // for each line in your data
$a = explode("-", $e); //break to prefix
$current = &$res;
while(count($a) > 1) { // create the array to that specific place if needed
$key = array_shift($a); // take the first key
if (!isset($current[$key])) // if the path not exist yet create empty array
$current[$key] = array();
$current = &$current[$key];
}
$current[] = $e; // found the right path so add the element
}
The full result will be in $res.
I'd probably do something along the lines of:
Could be more efficient if more time was spent on it.
<?php
$random = '15-02-01-0000
15-02-02-0000
15-02-03-0000
15-02-04-0000
15-02-05-0000
15-02-10-0000
15-02-10-9100
15-02-10-9101
15-15-81-0000
15-15-81-0024';
$lines = explode(PHP_EOL, $random);
$accounts = return_count($lines);
var_dump($accounts);
function return_count($lines){
$count_accounts = array();
$possibilties = array();
if(is_array($lines) && !empty($lines)){
foreach($lines as $val){
$line = explode('-', $val);
array_push($possibilties, $line[0], $line[0] . '-' . $line[1], $line[0] . '-' . $line[1] . '-' . $line[2]);
}
foreach($possibilties as $pos){
if(!isset($count_accounts[$pos])){ $count_accounts[$pos] = 0;}
if(search_array($pos, $lines)){
$count_accounts[$pos]++;
}
}
}
return $count_accounts;
}
function search_array($string, $array){
$found = 0;
if(is_array($array) && !empty($array)){
foreach($array as $val){
if (strpos($val, $string) !== false) {
$found = 1;
}
}
if($found == 1){
return true;
}else{
return false;
}
}else{
return false;
}
}
?>
Which returns:
array (size=10)
15 => int 10
'15-02' => int 8
'15-02-01' => int 1
'15-02-02' => int 1
'15-02-03' => int 1
'15-02-04' => int 1
'15-02-05' => int 1
'15-02-10' => int 3
'15-15' => int 2
'15-15-81' => int 2

PHP compare string for duplicatation

I have an array like so:
array{
[39] => src="http://www.google.com/jsapi">
[111] => src="http://www.example.com/wp-content/themes/code.js"
[55] => src="http://www.example.com/wp-content/themes/yui.js"
[1015] => src="wp-content/uploads/website.jpg"
}
Qeustion
What is the best way to find the difference of string ?
What I mean is to check if there are any duplicates.
src="http://www.example.com/wp-content/themes/ is repeated twice.
so if I then had an array like this:
array{
[39] => src="http://www.google.com/jsapi">
[55] => src="http://www.example.com/wp-content/themes/yui.js"
[1015] => src="wp-content/uploads/website.jpg"
}
http://www. is repeated twice.
so the Idea is to compare the string with another and find something that is duplicated and push it to an array ... thats all that I need :)
I am not saying it could be possible, but it would be nice if it could be :)
Community, feel free to optimize the code. I quickly wrote this out.
function findStrDuplicate($str1, $str2)
{
$duplicate = '';
for($i = 0; $i < min(strlen($str1), strlen($str2)); $i++) {
if($str1[$i] != $str2[$i]) {
break;
}
$duplicate .= $str1[$i];
}
return $duplicate;
}
function findArrayPrefixDuplicate($array)
{
$duplicatesArray = array();
for($i = 0; $i < count($array) - 1; $i++) {
for($j = $i+1; $j < count($array); $j++) {
$dup = findStrDuplicate($array[$i], $array[$j]);
if(!empty($dup)) {
$duplicatesArray[] = $dup;
}
}
}
return array_unique($duplicatesArray);
}
$data = array(
'src="http://www.google.com/jsapi"',
'src="http://www.example.com/wp-content/themes/code.js"',
'src="http://www.example.com/wp-content/themes/yui.js"',
'src="wp-content/uploads/website.jpg"'
);
// Remove src="..."
$data = array_map(function ($val) {
return substr($val, 5, strlen($val) - 1);
}, $data);
$result = findArrayPrefixDuplicate($data);
var_dump($result);
Result:
array
0 => string 'http://www.' (length=11)
2 => string 'http://www.example.com/wp-content/themes/' (length=41)
The following link should help with this: http://www.rogerethomas.com/b/14/php-search-string-for
You just need to change the else output to add it to the array and add a while loop in there if you are reiterating over multiple entries
I think that you will probably want to take a look at the suffix tree data structure. Take a look at this post for some ideas:
Fast String Search With Suffix Trees

Preparing a multi-dimensional array for an ExtJS tree control

please dont close this question as repeated one..........
I am new to php.
I am developing one tree grid in extjs.were i need to display field in tree format.so for front end i need to send the encoded data.
I want 2 functions for encoding and decoding a string variable,multidimensional array,variables with a set of delimiters.
For example if i am having an array.........
array(
array( "task" => "rose",
"duration" => 1.25,
"user" => 15
),
array( "task" => "daisy",
"duration" => 0.75,
"user" => 25,
),
array( "task" => "orchid",
"duration" => 1.15,
"user" => 7
),
array( "task" => "sunflower",
"duration" => 1.50,
"user" => 70
)
);
i want to encode all the array fields or single field as..........
array(
array( "task" => "rose",
"duration" => 1.25,
"user" => 15
),
array( "task" => "daisy",
"duration" => 0.75,
"user" => 25$sbaa,
),
array( "task" => "orchid",
"duration" => 1.15,
"user" => 7$!ass,
),
array( "task" => "sunflower",
"duration" => 1.50,
"user" => 70$!abc
)
);
So like this only i need to encode string,variables with delimiters.........
later all the encoded values to be decoded before its taken back to back end.....for this i have to use this plugin..........
encode.class.php...........
<?php
/*-------------------------
Author: Jonathan Pulice
Date: July 26th, 2005
Name: JPEncodeClass v1
Desc: Encoder and decoder using patterns.
-------------------------*/
class Protector
{
var $Pattern = "";
var $PatternFlip = "";
var $ToEncode = "";
var $ToDecode = "";
var $Decoded = "";
var $Encoded = "";
var $Bug = false;
var $DecodePattern = "";
function Debug($on = true)
{
$this->Bug = $on;
}
function Encode()
{
$ar = explode(":", $this->Pattern);
$enc = $this->ToEncode;
if ($this->Bug) echo "<!-- BEGIN ENCODING -->\n";
foreach ($ar as $num => $ltr)
{
switch ($ltr)
{
case "E":
$enc = base64_encode($enc);
break;
case "D":
$enc = base64_decode($enc);
break;
case "R":
$enc = strrev($enc);
break;
case "I":
$enc = $this->InvertCase($enc);
break;
}
if ($this->Bug) echo "<!-- {$ltr}: {$enc} -->\n";
}
if ($this->Bug) echo "<!-------------------->\n\n";
#$this->Encoded = ($enc == $this->Str) ? "<font color='red'>No Encoding/Decoding Pattern Detected!</font>" : $enc;
return $this->Encoded;
}
function Decode()
{
$pattern = ($this->DecodePattern != "") ? $this->DecodePattern : $this->Pattern;
//Reverse the pattern
$this->PatternFlip($pattern);
//make into an array
$ar = explode(":", $this->PatternFlip);
$t = ($this->Encoded == "") ? $this->ToDecode : $this->Encoded;
if ($this->Bug) echo "<!-- BEGIN DECODING -->\n";
foreach ($ar as $num => $ltr)
{
switch ($ltr)
{
case "E":
$t = base64_encode($t);
break;
case "D":
$t = base64_decode($t);
break;
case "R":
$t = strrev($t);
break;
case "I":
$t = $this->InvertCase($t);
break;
}
if ($this->Bug) echo "<!-- {$ltr}: {$t} -->\n";
}
if ($this->Bug) echo "<!-------------------->\n\n";
$this->Decoded = ($t == $this->Encoded) ? "<font color='red'>No Encoding/Decoding Pattern Detected!</font>" : $t;
return $this->Decoded;
}
function MakePattern($len = 10)
{
//possible letters
// E - Base64 Encode
// R - Reverse String
// I - Inverse Case
$poss = array('E','R', 'I');
//generate a string
for ( $i = 0 ; $i < $len ; $i++ )
{
$tmp[] = $poss[ rand(0,2) ];
}
//echo $str. "<br>";
//fix useless pattern section RR II
$str = implode(":", $tmp);
//fix
$str = str_replace( 'R:R:R:R:R:R' , 'R:E:R:E:R:E' , $str );
$str = str_replace( 'R:R:R:R:R' , 'R:E:R:E:R' , $str );
$str = str_replace( 'R:R:R:R' , 'R:E:R:E' , $str );
$str = str_replace( 'R:R:R' , 'R:E:R' , $str );
$str = str_replace( 'R:R' , 'R:E' , $str );
//fix
$str = str_replace( 'I:I:I:I:I:I' , 'I:E:I:E:I:E' , $str );
$str = str_replace( 'I:I:I:I:I' , 'I:E:I:E:I' , $str );
$str = str_replace( 'I:I:I:I' , 'I:E:I:E' , $str );
$str = str_replace( 'I:I:I' , 'I:E:I' , $str );
$str = str_replace( 'I:I' , 'I:E' , $str );
//string is good, set as pattern
$this->Pattern = $str;
return $this->Pattern; //if we need it
}
function PatternFlip($pattern)
{
//reverse the pattern
$str = strrev($pattern);
$ar = explode(":", $str);
foreach ($ar as $num => $ltr)
{
switch ($ltr)
{
case "E":
$tmp[] = "D";
break;
case "D":
$tmp[] = "E";
break;
case "R":
$tmp[] = "R";
break;
case "I":
$tmp[] = "I";
break;
}
}
$rev = implode(":", $tmp);
$this->PatternFlip = $rev;
return $this->PatternFlip;
}
// This is my custom Case Invertor!
// if you would like to use this in a script, please credit it to me, thank you
function InvertCase($str)
{
//Do initial conversion
$new = strtoupper( $str );
//spluit into arrays
$s = str_split( $str );
$n = str_split( $new );
//now we step through each letter, and if its the same as before, we swap it out
for ($i = 0; $i < count($s); $i++)
{
if ( $s[$i] === $n[$i] ) //SWAP THE LETTER
{
//ge the letter
$num = ord( $n[$i] );
//see if the ord is in the alpha ranges ( 65 - 90 | 97 - 122 )
if ( ( $num >= 65 AND $num <= 90 ) OR ( $num >= 97 AND $num <= 122 ) )
{
if ($num < 97 ) { $num = $num + 32; }
else { $num = $num - 32; }
$newchr = chr($num);
$n[$i] = $newchr;
}
}
}
//join the new string back together
$newstr = implode("", $n);
return $newstr;
}
}
?>
............
from this plugin i need to use encode and decode functions for my functions.........
if anyone can help me on this.......it will be very much useful for me.......
Why don't you use json_encode? Just do
$str=json_encode($array);
Then, send the data, and at the other end do
$array=json_decode($str);
Okay, let's break down the problem.
You have an array. Each element in the array is a hash. One (or more) of the values in that hash has to be encoded using that horrible abomination of a library. But the library can't process arrays.
We'll have to process the array ourselves.
<rant>
Before we begin, I'd just like to again express how horribly that "Protector" code is designed. It's written for PHP4 and is effectively spaghetti code wrapped in a class. It mis-uses properties, almost as if the user had some sort of mis-remembering about how Java's instance variables work and somehow thought it would be appropriate or sane to use PHP in the same way. If the author of the code doesn't look back on that revolting chunk of bytes now with utter disdain, something is severely wrong with him.
</rant>
I'm going to base my knowledge of this class on this copy of it, as the one you've provided is formatted even worse than the original.
First, let's create a list of inner array keys that we need to encode.
$keys_to_encode = array( 'user' );
Your example encoding lists only the user key as encodable. If you need to encode others, just add more elements to that array.
Now, let's prepare our "Protector." It seems to want you to either specify a pattern, or use the MakePattern method to have it create one. We're going to manually-specify one because MakePattern can come up with effectively useless combinations.
$stupid = new Protector();
$stupid->Pattern = 'E:I:E:R:D:I:E';
This will base64-encode, flip the case, base64 again, reverse it, un-base64, flip the case, and then re-base64. Be aware that PHP's base64 decoder "correctly" ignores bad padding and unexpected characters, which is the only reason the base64-reverse-unbase64 thing will work. The resulting string will look like gibberish to people that don't know what base64 looks like, and un-base64 to gibberish for people that to know what base64 looks like.
If you need to encode the values in a certain way, you'd do so by just changing the pattern. It's important that you either hard-code the pattern or store it somewhere with the data, because without it, you'll have a hard time doing the decode. (I mean, it can be done by hand, but you don't want to have to do that.) I expect that your boss is going to give you specific instructions on the pattern, given that you don't have an option in using this utter failure at a class.
Now it's time to process our data. Let's pretend that $in contains your original array.
$out = array();
foreach($in as $k => $target) {
foreach($keys_to_encode as $target_key) {
$stupid->ToEncode = $target[ $target_key ];
$target[ $target_key ] = $stupid->Encode();
}
$out[$k] = $target;
}
This loops through the array of hashes, then inside each hash, only the keys we want to encode are encoded. The encoded hash is placed in a new array, $out. This is what you'd pass to your tree widget.
Decoding is just as easy. You've stated that your goal is letting users edit certain data in the tree widget, and you seem to want to protect the underlying keys. This tells me that you probably only need to deal with one of the hashes at a time. Therefore, I'm going to write this decode sample using only one value, $whatever.
$stupidest = new Protector();
$stupidest->Pattern = 'E:I:E:R:D:I:E'; // SAME PATTERN!
$stupidest->ToDecode = $whatever;
$decoded = $stupidest->Decode();
Again, it's critical that you use the same decode pattern here.
As for the actual interaction with the tree widget, you're on your own there. I know only enough about ExtJS to know that it exists and that the GUI creators for it are really fun to play with.

PHP and RegEx: Split a string by commas that are not inside brackets (and also nested brackets)

Two days ago I started working on a code parser and I'm stuck.
How can I split a string by commas that are not inside brackets, let me show you what I mean:
I have this string to parse:
one, two, three, (four, (five, six), (ten)), seven
I would like to get this result:
array(
"one";
"two";
"three";
"(four, (five, six), (ten))";
"seven"
)
but instead I get:
array(
"one";
"two";
"three";
"(four";
"(five";
"six)";
"(ten))";
"seven"
)
How can I do this in PHP RegEx.
Thank you in advance !
You can do that easier:
preg_match_all('/[^(,\s]+|\([^)]+\)/', $str, $matches)
But it would be better if you use a real parser. Maybe something like this:
$str = 'one, two, three, (four, (five, six), (ten)), seven';
$buffer = '';
$stack = array();
$depth = 0;
$len = strlen($str);
for ($i=0; $i<$len; $i++) {
$char = $str[$i];
switch ($char) {
case '(':
$depth++;
break;
case ',':
if (!$depth) {
if ($buffer !== '') {
$stack[] = $buffer;
$buffer = '';
}
continue 2;
}
break;
case ' ':
if (!$depth) {
continue 2;
}
break;
case ')':
if ($depth) {
$depth--;
} else {
$stack[] = $buffer.$char;
$buffer = '';
continue 2;
}
break;
}
$buffer .= $char;
}
if ($buffer !== '') {
$stack[] = $buffer;
}
var_dump($stack);
Hm... OK already marked as answered, but since you asked for an easy solution I will try nevertheless:
$test = "one, two, three, , , ,(four, five, six), seven, (eight, nine)";
$split = "/([(].*?[)])|(\w)+/";
preg_match_all($split, $test, $out);
print_r($out[0]);
Output
Array
(
[0] => one
[1] => two
[2] => three
[3] => (four, five, six)
[4] => seven
[5] => (eight, nine)
)
You can't, directly. You'd need, at minimum, variable-width lookbehind, and last I knew PHP's PCRE only has fixed-width lookbehind.
My first recommendation would be to first extract parenthesized expressions from the string. I don't know anything about your actual problem, though, so I don't know if that will be feasible.
I can't think of a way to do it using a single regex, but it's quite easy to hack together something that works:
function process($data)
{
$entries = array();
$filteredData = $data;
if (preg_match_all("/\(([^)]*)\)/", $data, $matches)) {
$entries = $matches[0];
$filteredData = preg_replace("/\(([^)]*)\)/", "-placeholder-", $data);
}
$arr = array_map("trim", explode(",", $filteredData));
if (!$entries) {
return $arr;
}
$j = 0;
foreach ($arr as $i => $entry) {
if ($entry != "-placeholder-") {
continue;
}
$arr[$i] = $entries[$j];
$j++;
}
return $arr;
}
If you invoke it like this:
$data = "one, two, three, (four, five, six), seven, (eight, nine)";
print_r(process($data));
It outputs:
Array
(
[0] => one
[1] => two
[2] => three
[3] => (four, five, six)
[4] => seven
[5] => (eight, nine)
)
Clumsy, but it does the job...
<?php
function split_by_commas($string) {
preg_match_all("/\(.+?\)/", $string, $result);
$problem_children = $result[0];
$i = 0;
$temp = array();
foreach ($problem_children as $submatch) {
$marker = '__'.$i++.'__';
$temp[$marker] = $submatch;
$string = str_replace($submatch, $marker, $string);
}
$result = explode(",", $string);
foreach ($result as $key => $item) {
$item = trim($item);
$result[$key] = isset($temp[$item])?$temp[$item]:$item;
}
return $result;
}
$test = "one, two, three, (four, five, six), seven, (eight, nine), ten";
print_r(split_by_commas($test));
?>
I feel that its worth noting, that you should always avoid regular expressions when you possibly can. To that end, you should know that for PHP 5.3+ you could use str_getcsv(). However, if you're working with files (or file streams), such as CSV files, then the function fgetcsv() might be what you need, and its been available since PHP4.
Lastly, I'm surprised nobody used preg_split(), or did it not work as needed?
Maybe a bit late but I've made a solution without regex which also supports nesting inside brackets. Anyone let me know what you guys think:
$str = "Some text, Some other text with ((95,3%) MSC)";
$arr = explode(",",$str);
$parts = [];
$currentPart = "";
$bracketsOpened = 0;
foreach ($arr as $part){
$currentPart .= ($bracketsOpened > 0 ? ',' : '').$part;
if (stristr($part,"(")){
$bracketsOpened ++;
}
if (stristr($part,")")){
$bracketsOpened --;
}
if (!$bracketsOpened){
$parts[] = $currentPart;
$currentPart = '';
}
}
Gives me the output:
Array
(
[0] => Some text
[1] => Some other text with ((95,3%) MSC)
)
I am afraid that it could be very difficult to parse nested brackets like
one, two, (three, (four, five))
only with RegExp.

Categories