PHP break string into two parts - php

Note: I can't use break or next line functions as i am using FPDF
I am having a problem with php strings. I am having a string where i want to show atmost 12 characters in first row and remaining in second row. So basically i want to break string into two parts and assign to two variables so that i can print those two variables. I have tried following code :-
if($length > 12)
{
$first400 = substr($info['business_name'], 0, 12);
$theRest = substr($info['business_name'], 11);
$this->Cell(140,22,strtoupper($first400));
$this->Ln();
$this->Cell(140,22,strtoupper($theRest));
$this->Ln();
}
But using this I am getting as shown below :
Original String : The Best Hotel Ever
Output :
The Best Hot
Tel Ever
It is breaking a word, i don't want to break the word, just check the length and if within 12 characters all the words are complete then print next word in next line. Like this :
Desired OutPut:
The Best
Hotel Ever
Any suggestions ?

I see no built-in function to do it, however you could explode on spaces, and re-build your string until the length with the next words get over 12, everything else going to the second part :
$string = 'The Best Hotel Ever';
$exp = explode(' ', $string);
if (strlen($exp[0]) < 12) {
$tmp = $exp[0];
$i = 1;
while (strlen($tmp . ' ' . $exp[$i]) < 12) {
$tmp .= " " . $exp[$i];
$i++;
}
$array[0] = $tmp;
while (isset($exp[$i])) {
$array[1] .= ' ' . $exp[$i];
$i++;
}
$array[1] = trim($array[1]);
} else {
$array[0] = '';
$array[1] = trim(implode (' ', $exp));
}
var_dump($array);
// Output : array(2) { [0]=> string(8) "The Best" [1]=> string(10) "Hotel Ever" }
// $string1 = 'The';
// array(2) { [0]=> string(3) "The" [1]=> string(0) "" }
// $string2 = 'Thebesthotelever';
// array(2) { [0]=> string(0) "" [1]=> string(16) "Thebesthotelever" }

Im not too crash hot on PHP but it seems to be a simple case of which element of the string you are accessing is futher across from where you want to be:
Try:
if($length > 12)
{
$first400 = substr($info['business_name'], 0, 8);
$theRest = substr($info['business_name'], 11);
$this->Cell(140,22,strtoupper($first400));
$this->Ln();
$this->Cell(140,22,strtoupper($theRest));
$this->Ln();
}
For further help check out because you need to remember to count from zero up:
http://php.net/manual/en/function.substr.php

Related

Remove lines contains specific number of words

My question can be understood with an example given below :
Suppose This is the text file, which contains these lines :
hello this is my word file and this is line number 1
hello this is second line and this is some text
hello this is third line and again some text
jhasg djgha sdgasjhgdjasgh jdkh
sdhgfkjg sdjhgf sjkdghf sdhf
s hdg fjhsgd fjhgsdj gfj ksdgh
I want to get each line into a variable
then get all the words of that line into an array
then compare that array which contains words of that line WITH all the words of next lines
if the number of matches of words is more than 3 that line is deleted
so in the above example the output should be :
hello this is my word file and this is line number 1
jhasg djgha sdgasjhgdjasgh jdkh
sdhgfkjg sdjhgf sjkdghf sdhf
s hdg fjhsgd fjhgsdj gfj ksdgh
Because hello this is line is more than 3 words, so the lines containing those words are deleted. Please note that the first line is not deleted because it is unique....
I tried to code myself and created a mess which created 200mb text file with the unlimited number of first line text. Anyways here is the code, dont execute it else you can end up having your hard disk full.
<?php
$fileA = fopen("names.txt", "r");
$fileB = fopen("anothernames.txt", "r");
$fileC = fopen("uniquenames.txt", "w");
while(!feof($fileA))
{
$line = fgets($fileA);
$words = explode(" ", $line);
$size = count($words);
while(!feof($fileA))
{
$line1 = fgets($fileB);
$words1 = explode(" ", $line1);
$size1 = count($words1);
$c=0;
for($i=0; $i<$size; $i++)
{
for($j=0; $j<$size1; $j++)
{
if($words[$i]==$words1[$j])
$c++;
}
}
if($c<3)
fwrite($fileC, $line);
}
}
fclose($fileA);
fclose($fileB);
fclose($fileC);
?>
Thanks
An easy approach would be the following:
read all the lines, using file()
create an array, containing the sentence, indexed by each word.
finally build a blacklist of every sentence which appears in any of the arrays, counting more than 3 entries for any word.
Then print every line, except the blacklisted:
Example:
<?php
$lines = array("hello this is my word file and this is line number 1",
"hello this is second line and this is some text",
"hello this is third line and again some text",
"jhasg djgha sdgasjhgdjasgh jdkh",
"sdhgfkjg sdjhgf sjkdghf sdhf",
"s hdg fjhsgd fjhgsdj gfj ksdgh");
//$lines = file("path/to/file");
$result = array();
//build "count-per-word" array
foreach ($lines AS $line){
$words = explode(" ", $line);
foreach ($words AS $word){
$word = strtolower($word);
if (isset($result[$word]))
$result[$word][] = $line;
else
$result[$word] = array($line);
}
}
//Blacklist each sentence, containing a word appearing in 3 sentences.
$blacklist = array();
foreach ($result AS $word => $entries){
if (count($entries) >= 3){
foreach($entries AS $entry){
$blacklist[] = $entry;
}
}
}
//list all not blacklisted.
foreach ($lines AS $line){
if (!in_array($line, $blacklist))
echo $line."<br />";
}
?>
Output:
jhasg djgha sdgasjhgdjasgh jdkh
sdhgfkjg sdjhgf sjkdghf sdhf
s hdg fjhsgd fjhgsdj gfj ksdgh
Note, that this will also blacklist a single sentence containing 3 times the same word, such as "Foo Foo Foo bar".
To aovid this, check if the line is already "known" for a certain word before pushing it to the array:
foreach ($words AS $word){
if (isset($result[$word])){
if (!in_array($line, $result[$word])){
$result[$word][] = $line;
}
}else
$result[$word] = array($line);
}
#second
while(!feof($fileA))
#should be
while(!feof($fileB))
and
if($c<3)
fwrite($fileC, $line);
#should
if($c<3){
fwrite($fileC, $line);
continue 2;
}
but
then compare that array which contains words of that line WITH all the words of next lines
makes only sence when you compare the file with itself!
EDIT:my post makes no sence at all, read note from prev post!
Why not just array_intersect?
php > $l1 = 'hello this is my word file and this is line number 1';
php > $l2 = 'hello this is second line and this is some text';
php > $a1 = explode(" ", $l1);
php > $a2 = explode(" ", $l2);
php > var_dump(array_intersect($a1, $a2));
array(7) {
[0]=>
string(5) "hello"
[1]=>
string(4) "this"
[2]=>
string(2) "is"
[6]=>
string(3) "and"
[7]=>
string(4) "this"
[8]=>
string(2) "is"
[9]=>
string(4) "line"
}
if (count of intersection >= 3) {
skip line
}
Or am I reading your "matching" too loosely?

How to remove or trim special characters (\n) from Array?

I have created a Array and are not able to echo values from it. Below I have copy pasted source code results from my browser. As you can see "]=> starts on new line. How can I solve this
using this function:
function remap_alternating(array $values) {
$remapped = array();
for($i = 0; $i < count($values) - 1; $i += 2) {
$remapped[strip_tags(trim($values[$i], " "))] = strip_tags(trim($values[$i + 1], " "));
}
return $remapped;
}
$mapped = remap_alternating($matches[0]);
$keys = str_replace( ':', '', array_keys($mapped) );
$values = array_values($mapped);
$mapped = array_combine($keys, $values);
Result of var_dump($mapped); (Copy Paste from Browser Source Code)
array(32) {
["Age
"]=>
string(9) "21 Yrs.
"
["Ethnicity
"]=>
string(6) "Black
"
["Location
"]=>
string(36) "Dubai, Dubayy, United Arab Emirates
"
My question is how I can get echo $mapped[Age];to work?
Thank you
You can specify the characters to trim in the second argument of trim(): http://us2.php.net/trim
You look to be specifying only " ", in the trim() function you're using. Leave the second argument blank so it will trim the default characters which includes \n.

Random But Unique Pairings, with Conditions

I need some help/direction in setting up a PHP script to randomly pair up items in an array.
The items should be randomly paired up each time.
The items should not match themselves ( item1-1 should not pair up with item1-1 )
Most of the items have a mate (ie. item1-1 and item1-2). The items should not be paired with their mate.
I've been playing around with the second script in this post but, I haven't been able to make any progress. Any help is appreciated.
Very simple approach, but hopefully helpful to you:
(mates, if grouped in an array (e.g. array('a1', 'a2')), will not be paired.)
function matchUp($array) {
$result = array();
while($el = array_pop($array)) {
shuffle($array);
if (sizeof($array) > 0) {
$candidate = array_pop($array);
$result[] = array(
array_pop($el),
array_pop($candidate)
);
if (sizeof($el) > 0) {
$array[] = $el;
}
if (sizeof($candidate) > 0) {
$array[] = $candidate;
}
}
else {
$result[] = array(array_pop($el));
}
}
return $result;
}
$array = array(
array('a1', 'a2'),
array('b1', 'b2'),
array('c1'),
array('d1'),
array('e1', 'e2'),
array('f1'),
array('g1', 'g2'),
);
Update:
foreach(matchUp($array) as $pair) {
list($a, $b) = $pair + array(null, null);
echo '<div style="border: solid 1px #000000;">' . $a . ' + ' . $b . '</div>';
}
With the randomness, there is no guarantee that a full correct solution will be reached.
Certain problem sets are more likely to be solved than others. Some will be impossible.
You can configure how many times it will try to achieve a good solution. After the specified number of tries it will return the best solution it could find.
function pairUp (array $subjectArray) {
// Config options
$tries = 50;
// Variables
$bestPaired = array();
$bestUnpaired = array();
for($try = 1; $try <= 50; $try++) {
$paired = array();
$unpaired = array();
$toBePaired = $subjectArray;
foreach($subjectArray as $subjectIndex => $subjectValue) {
// Create array without $thisValue anywhere, from the unpaired items
$cleanArray = array();
foreach($toBePaired as $index => $value) {
if($value != $subjectValue) {
array_push($cleanArray, array(
'index' => $index,
'value' => $value
));
}
}
sort($cleanArray); // reset indexes in array
// See if we have any different values left to match
if(count($cleanArray) == 0) {
array_push($unpaired, $subjectValue);
continue;
}
// Get a random item from the clean array
$randomIndex = rand(0,count($cleanArray)-1);
// Store this pair
$paired[$subjectIndex] = $subjectValue . '-' . $cleanArray[$randomIndex]['value'];
// This item has been paired, remove it from unpairedItems
unset($toBePaired[$cleanArray[$randomIndex]['index']]);
sort($toBePaired);
}
// Decide if this is our best try
if(count($paired) > count($bestPaired)) {
$bestPaired = $paired;
$bestUnpaired = $unpaired;
}
// If we had no failures, this was a perfect try - finish
if(count($unpaired) == 0) { $break; }
}
// We're done, send our array of pairs back.
return array(
'paired' => $bestPaired,
'unpaired' => $bestUnpaired
);
}
var_dump(pairUp(array('a','b','c','d','e','a','b','c','d','e')));
/*
Example output:
array(2) {
["paired"]=>
array(10) {
[0]=>
string(3) "a-b"
[1]=>
string(3) "b-c"
[2]=>
string(3) "c-d"
[3]=>
string(3) "d-e"
[4]=>
string(3) "e-a"
[5]=>
string(3) "a-b"
[6]=>
string(3) "b-e"
[7]=>
string(3) "c-d"
[8]=>
string(3) "d-c"
[9]=>
string(3) "e-a"
}
["unpaired"]=>
array(0) {
}
}
*/
Case 1: if all elements had a mate
If all elements had a mate, the following solution would work, although I don't know if it would be perfectly random (as in, all possible outputs having the same probability):
Shuffle the list of elements, keeping mates together
original list = (a1,a2),(b1,b2),(c1,c2),(d1,d2)
shuffled = (c1,c2),(d1,d2),(a1,a2),(b1,b2)
Shift the second mate to the right. The matches have been formed.
shifted = (c1,b2),(d1,c2),(a1,d2),(b1,a2)
(Edit1: if applied exactly as described, there is no way a1 ends up matched with b1. So, before shifting, you may want to throw a coin for each pair of mates to decide whether they should change their order or not.)
Case 2: if only some elements have a mate
Since in your question only some elements will have a mate, I guess one could come up with the following:
Arbitrarily pair up those elements who don't have a mate. There should be an even number of such elements. Otherwise, the total number of elements would be odd, so no matching could be done in the first place.
original list = (a1,a2),(b1,b2),c1,d1,e1,f1 // c1,d1,e1 and f1 don't have mates
list2 = (a1,a2),(b1,b2),(c1,d1),(e1,f1) // pair them up
Shuffle and shift as in case 1 to form the matches.
shuffled = (e1,f1),(a1,a2),(c1,d1),(b1,b2)
shifted = (e1,b2),(a1,f1),(c1,a2),(b1,d1)
Again, I don't know if this is perfectly random, but I think it should work.
(Edit2: simplified the solution)
(Edit3: if the total number of elements is odd, someone will be left without a match, so pick an element randomly at the beginning to leave it out and then apply the algorithm above).

Parsing Text File

I need an advice.
I need to scrap and parse text file (using for currency exchange rates). Here we are, a small snippet from this file:
c057z110323
h057z110323
a057z110323
b012z110323
c058z110324
h058z110324
a058z110324
c059z110325
h059z110325
a059z110325
c060z110328
h060z110328
a060z110328
c061z110329
h061z110329
a061z110329
c062z110330
h062z110330
a062z110330
b013z110330
c063z110331
h063z110331
a063z110331
c064z110401
h064z110401
a064z110401
c065z110404
h065z110404
a065z110404
c066z110405
h066z110405
a066z110405
c067z110406
h067z110406
a067z110406
b014z110406
c068z110407
h068z110407
a068z110407
c069z110408
h069z110408
a069z110408
As you may see there's a lot of lines (in original file there are about 80000 of lines (few lines per day are being added).
String format is as following:
A000112233
where
A - type
000 - number of the file (created this year)
11 - year
22 - month
33 - day
I'm getting 25 latest lines from from the file using following snippet:
$file = "http://www.nbp.pl/kursy/xml/dir.txt";
$data = file($file);
$count = count($data);
for($i = $count - 25; $i < $count; $i++)
{
if( substr($data[$i], 0, 1) === 'a' )
{
$latest[] = $data[$i];
}
}
I need to get only lines starting with "a". The output array looks as following:
array(8) {
[0]=>
string(13) "a062z110330
"
[1]=>
string(13) "a063z110331
"
[2]=>
string(13) "a064z110401
"
[3]=>
string(13) "a065z110404
"
[4]=>
string(13) "a066z110405
"
[5]=>
string(13) "a067z110406
"
[6]=>
string(13) "a068z110407
"
[7]=>
string(13) "a069z110408
"
}
Now I need to compare every array element to get the latest item from the latest working day before current date. I'm acheiving it this way:
$i = 1;
foreach($latest as $row)
{
$plural = ($i > 1) ? 's' : null;
if( substr(trim($row), -6) === date("ymd", strtotime("-" . $i . " day" . $plural) )
{
$filename = $row;
break;
}
$i++;
}
It's working quite OK, however I'm facing one big problem. I'm unable to sort $latest array by the latest six characters. I tried doing this using sort(), rsort(). None of them worked good for me.
Can anybody help me with this issue or maybe has better approach to do what I'm looking for.
When you do
for($i = $count - 25; $i < $count; $i++)
{
if( substr($data[$i], 0, 1) === 'a' )
{
$latest[] = $data[$i];
}
}
use date as a key in $latest array:
for($i = $count - 25; $i < $count; $i++)
{
if( substr($data[$i], 0, 1) === 'a' )
{
$key = (int) substr($data[$i], -6);
$latest[$key] = $data[$i];
}
}
Then you can sort by key like:
ksort($latest);
You need to use a custom sort method. You can use usort to write your own comparison function : http://php.net/manual/en/function.usort.php
From the manual
function cmp($a, $b) {
if ($a == $b) {
return 0;
}
return ($a < $b) ? -1 : 1;
}
$a = array(3, 2, 5, 6, 1);
usort($a, "cmp");
The comparison function must return an
integer less than, equal to, or
greater than zero if the first
argument is considered to be
respectively less than, equal to, or
greater than the second.
Since you're only asking how to sort an array of strings by their last six characters:
Use usort:
function sortfunc($a, $b) {
return strcmp(substr($a, -6), substr($b, -6));
}
usort($latest, 'sortfunc');
You may need to trim() your lines first or the newlines and/or carriage return characters will be part of the last 6 characters.

Split long string into little ones. - trying to find an elegant way for doing so

If the string is bigger then 50 chars long, I need to split it.
The maximum allowed is 3 chunks of 50. It could be less then 50 but never more then 150.
I don't need any special chars to be added, or to serve as "splitters"; I can break the string anywhere, no problem, since the propose is not for showing it to the user.
if (strlen($street) > 50)
{
$streetPart1 = substr($street,0,50);
$streetPart2 = substr($street,51,100);
$streetPart3 = substr($street,101,150);
}
Is there a more elegant way for doing this?
UPDATE:
An example of what would arrive next:
if (strlen($street) > 50)
{
$streetPart1 = substr($street,0,50);
$streetPart2 = substr($street,51,100);
$streetPart3 = substr($street,101,150);
if(!empty($streetPart2) && empty($streetPart3)
{
//add part2 only.
}elseif(!empty($streetPart2 && !empty($streetPart3))
{
//add part 2 and part 3
}
}
Thanks a lot.
MEM
You may simply use str_split:
$parts = str_split($string, 50);
// if you want to have vars instead of array:
list($part1, $part2, $part3) = str_split($string, 50);
Check the PHP's wordwrap() function.
http://php.net/manual/en/function.wordwrap.php
And check out the explode() function
http://php.net/manual/en/function.explode.php
<?
function wrapAndCropToArray($text, $width, $lines)
{
$ret = array_slice(
explode("\n",wordwrap($text,$width,"\n",true))
, 0
, $lines+1
);
if(isset($ret[$lines]))
$ret[$lines] = "...";
return $ret;
}
$test = "aadfuiosdy 34 123 412 341f2 38947 1029 384h120 39uh4 19023h 41234";
var_dump(wrapAndCropToArray($test,10,3));
?>
Will output:
array(4) {
[0]=>
string(10) "aadfuiosdy"
[1]=>
string(10) "34 123 412"
[2]=>
string(5) "341f2"
[3]=>
string(3) "..."
}

Categories